IT TIP

Spring MVC가 404로 응답하고“DispatcherServlet에서 URI […]를 사용하는 HTTP 요청에 대한 매핑을 찾을 수 없음”을보고하는 이유는 무엇입니까?

itqueen 2020. 10. 12. 21:17
반응형

Spring MVC가 404로 응답하고“DispatcherServlet에서 URI […]를 사용하는 HTTP 요청에 대한 매핑을 찾을 수 없음”을보고하는 이유는 무엇입니까?


Tomcat에 배포 된 Spring MVC 애플리케이션을 작성 중입니다. 최소한의 완전하고 검증 가능한 다음 예제를 참조하십시오.

public class Application extends AbstractAnnotationConfigDispatcherServletInitializer {
    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[] { };
    }
    protected Class<?>[] getServletConfigClasses() {
        return new Class<?>[] { SpringServletConfig.class };
    }
    protected String[] getServletMappings() {
        return new String[] { "/*" };
    }
}

어디 SpringServletConfig있다

@Configuration
@ComponentScan("com.example.controllers")
@EnableWebMvc
public class SpringServletConfig {
    @Bean
    public InternalResourceViewResolver resolver() {
        InternalResourceViewResolver vr = new InternalResourceViewResolver();
        vr.setPrefix("/WEB-INF/jsps/");
        vr.setSuffix(".jsp");
        return vr;
    }
}

마지막으로 @Controller패키지에com.example.controllers

@Controller
public class ExampleController {
    @RequestMapping(path = "/home", method = RequestMethod.GET)
    public String example() {
        return "index";
    }
}

내 응용 프로그램의 컨텍스트 이름은 Example입니다. 내가 요청을 보낼 때

http://localhost:8080/Example/home

응용 프로그램은 HTTP 상태 404로 응답하고 다음을 기록합니다.

WARN  o.s.web.servlet.PageNotFound - No mapping found for HTTP request with URI `[/Example/WEB-INF/jsps/index.jsp]` in `DispatcherServlet` with name 'dispatcher'

/WEB-INF/jsps/index.jspSpring MVC가 내 컨트롤러를 사용하여 요청을 처리하고 JSP로 전달 하는 데 JSP 리소스가 있는데 왜 404로 응답합니까?


이 경고 메시지에 대한 질문에 대한 정식 게시물입니다.


표준 Spring MVC 애플리케이션은 DispatcherServletServlet 컨테이너에 등록한를 통해 모든 요청을 처리합니다 .

DispatcherServlet의에서 외모 ApplicationContext와는 가능한 경우 ApplicationContext에 등록 ContextLoaderListener이 설정의 요청을 제공하는 로직이 필요 특별한 콩을 위해. 이러한 빈은 문서에 설명되어 있습니다 .

틀림없이 가장 중요한 유형 HandlerMapping맵의

핸들러에 대한 수신 요청과 HandlerMapping구현에 따라 세부 사항이 다른 일부 기준에 기반한 전 처리기 및 후 처리기 (핸들러 인터셉터) 목록 . 가장 널리 사용되는 구현은 주석이 달린 컨트롤러를 지원하지만 다른 구현도 존재합니다.

의 javadoc는HandlerMapping 더는 구현이 행동해야하는 방법에 대해 설명합니다.

(가) DispatcherServlet이 유형의 모든 콩을 발견하고 어떤 순서로 등록 (사용자 정의 할 수 있음). 요청을 제공하는 동안 DispatcherServlet은 이러한 HandlerMapping객체를 반복 하고 각 객체를 테스트 getHandler하여 표준으로 표시되는 수신 요청을 처리 할 수있는 객체 를 찾습니다 HttpServletRequest. 4.3.x에서 현재로, 이 중 하나를 찾을 수없는 경우 , 그것은 경고 기록 이 표시되는지를

이름이 SomeName 인 URI가 [/some/path]있는 HTTP 요청에 대한 매핑이 없습니다.DispatcherServlet

그리고 하나는 를 발생 NoHandlerFoundException즉시 404 찾을 수 없음 상태 코드로 응답을 얻어냅니다.

내 요청을 처리 할 수있는를 DispatcherServlet찾지 못한 이유는 무엇 HandlerMapping입니까?

가장 일반적인 HandlerMapping구현은이며 RequestMappingHandlerMapping, @Controller빈을 핸들러 (실제로 @RequestMapping주석이 달린 메서드) 등록하는 것을 처리합니다 . 이 유형의 bean을 직접 선언 @Bean하거나 ( <bean>또는 기타 메커니즘을 사용 하여) 내장 옵션을 사용할 수 있습니다 . 이것들은:

  1. 당신의 주석 @Configuration과 클래스를 @EnableWebMvc.
  2. <mvc:annotation-driven />XML 구성에서 멤버를 선언 하십시오.

위의 링크에서 설명했듯이이 두 가지 모두 RequestMappingHandlerMapping빈 (및 기타 여러 가지)을 등록합니다. 그러나 HandlerMapping핸들러 없이는별로 유용하지 않습니다. RequestMappingHandlerMapping일부 @Controller빈을 예상 하므로 @BeanJava 구성의 메서드 또는 <bean>XML 구성의 선언을 통해 또는 @Controller둘 중 하나에서 주석 달린 클래스 의 구성 요소 스캔을 통해이를 선언 해야합니다. 이 콩이 있는지 확인하십시오.

경고 메시지와 404가 표시되고 위의 모든 사항을 올바르게 구성한 경우 감지 된 주석 처리기 메서드에서 처리하지 않는 잘못된 URI로 요청을 보내는 것@RequestMapping 입니다.

spring-webmvc라이브러리 이벤트 다른 내장 HandlerMapping구현. 예 : BeanNameUrlHandlerMapping지도

URL에서 슬래시 ( "/")로 시작하는 이름을 가진 Bean으로

언제든지 직접 작성할 수 있습니다. 분명히, 당신이 보내는 요청이 등록 된 HandlerMapping객체의 핸들러 중 적어도 하나와 일치하는지 확인해야합니다 .

암시 적 또는 명시 적으로 등록하지 당신이 경우 HandlerMapping콩 (또는 경우 detectAllHandlerMappings이다 true)의 DispatcherServlet레지스터 일부 기본값을 . 이들은 클래스 DispatcherServlet.properties와 동일한 패키지에 정의되어 DispatcherServlet있습니다. 그들은이다 BeanNameUrlHandlerMappingDefaultAnnotationHandlerMapping(과 유사하다 RequestMappingHandlerMapping하지만 사용되지 않음).

디버깅

Spring MVC는 RequestMappingHandlerMapping. 예를 들어, @Controller좋아요

@Controller
public class ExampleController {
    @RequestMapping(path = "/example", method = RequestMethod.GET, headers = "X-Custom")
    public String example() {
        return "example-view-name";
    }
}

will log the following at INFO level

Mapped "{[/example],methods=[GET],headers=[X-Custom]}" onto public java.lang.String com.spring.servlet.ExampleController.example()

This describes the mapping registered. When you see the warning that no handler was found, compare the URI in the message to the mapping listed here. All the restrictions specified in the @RequestMapping must match for Spring MVC to select the handler.

Other HandlerMapping implementations log their own statements that should hint to their mappings and their corresponding handlers.

Similarly, enable Spring logging at DEBUG level to see which beans Spring registers. It should report which annotated classes it finds, which packages it scans, and which beans it initializes. If the ones you expected aren't present, then review your ApplicationContext configuration.

Other common mistakes

A DispatcherServlet is just a typical Java EE Servlet. You register it with your typical <web.xml> <servlet-class> and <servlet-mapping> declaration, or directly through ServletContext#addServlet in a WebApplicationInitializer, or with whatever mechanism Spring boot uses. As such, you must rely on the url mapping logic specified in the Servlet specification, see Chapter 12. See also

With that in mind, a common mistake is to register the DispatcherServlet with a url mapping of /*, returning a view name from a @RequestMapping handler method, and expecting a JSP to be rendered. For example, consider a handler method like

@RequestMapping(path = "/example", method = RequestMethod.GET)
public String example() {
    return "example-view-name";
}

with an InternalResourceViewResolver

@Bean
public InternalResourceViewResolver resolver() {
    InternalResourceViewResolver vr = new InternalResourceViewResolver();
    vr.setPrefix("/WEB-INF/jsps/");
    vr.setSuffix(".jsp");
    return vr;
}

you might expect the request to be forwarded to a JSP resource at the path /WEB-INF/jsps/example-view-name.jsp. This won't happen. Instead, assuming a context name of Example, the DisaptcherServlet will report

No mapping found for HTTP request with URI [/Example/WEB-INF/jsps/example-view-name.jsp] in DispatcherServlet with name 'dispatcher'

Because the DispatcherServlet is mapped to /* and /* matches everything (except exact matches, which have higher priority), the DispatcherServlet would be chosen to handle the forward from the JstlView (returned by the InternalResourceViewResolver). In almost every case, the DispatcherServlet will not be configured to handle such a request.

Instead, in this simplistic case, you should register the DispatcherServlet to /, marking it as the default servlet. The default servlet is the last match for a request. This will allow your typical servlet container to chose an internal Servlet implementation, mapped to *.jsp, to handle the JSP resource (for example, Tomcat has JspServlet), before trying with the default servlet.

That's what you're seeing in your example.


I resolved my issue when in addition to described before:`

@Bean
public InternalResourceViewResolver resolver() {
    InternalResourceViewResolver vr = new InternalResourceViewResolver();
    vr.setPrefix("/WEB-INF/jsps/");
    vr.setSuffix(".jsp");
    return vr;
}

added tomcat-embed-jasper:

<dependency>
       <groupId>org.apache.tomcat.embed</groupId>
        <artifactId>tomcat-embed-jasper</artifactId>
       <scope>provided</scope>
</dependency>

` from: JSP file not rendering in Spring Boot web application


In my case, I was following the Interceptors Spring documentation for version 5.1.2 (while using Spring Boot v2.0.4.RELEASE) and the WebConfig class had the annotation @EnableWebMvc, which seemed to be conflicting with something else in my application that was preventing my static assets from being resolved correctly (i.e. no CSS or JS files were being returned to the client).

After trying a lot of different things, I tried removing the @EnableWebMvc and it worked!

Edit: Here's the reference documentation that says you should remove the @EnableWebMvc annotation

Apparently in my case at least, I'm already configuring my Spring application (although not by using web.xml or any other static file, it's definitely programmatically), so it was a conflict there.


I came across another reason for the same error. This could also be due to the class files not generated for your controller.java file. As a result of which the the dispatcher servlet mentioned in web.xml is unable to map it to the appropriate method in the controller class.

@Controller
Class Controller{
@RequestMapping(value="/abc.html")//abc is the requesting page
public void method()
{.....}
}

In eclipse under Project->select clean ->Build Project.Do give a check if the class file has been generated for the controller file under builds in your workspace.


For me, I found that my target classes were generated in a folder pattern not same as source. This is possibly in eclipse I add folders for containing my controllers and not add them as packages. So I ended up defining incorrect path in spring config.

My target class was generating classes under app and I was referring to com.happy.app

<context:annotation-config />
<context:component-scan
    base-package="com.happy.app"></context:component-scan> 

I added packages (not folders) for com.happy.app and moved the files from folders to packages in eclipse and it resolved the issue.


Clean your server. Maybe delete the server and add the project once again and Run.

  1. Stop the Tomcat server

  2. Right click the server and select "Clean"

  3. Right click server again and select "Clean Tomcat Work Directory"

참고URL : https://stackoverflow.com/questions/41577234/why-does-spring-mvc-respond-with-a-404-and-report-no-mapping-found-for-http-req

반응형