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.jsp
Spring MVC가 내 컨트롤러를 사용하여 요청을 처리하고 JSP로 전달 하는 데 JSP 리소스가 있는데 왜 404로 응답합니까?
이 경고 메시지에 대한 질문에 대한 정식 게시물입니다.
표준 Spring MVC 애플리케이션은 DispatcherServlet
Servlet 컨테이너에 등록한를 통해 모든 요청을 처리합니다 .
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>
또는 기타 메커니즘을 사용 하여) 내장 옵션을 사용할 수 있습니다 . 이것들은:
- 당신의 주석
@Configuration
과 클래스를@EnableWebMvc
. <mvc:annotation-driven />
XML 구성에서 멤버를 선언 하십시오.
위의 링크에서 설명했듯이이 두 가지 모두 RequestMappingHandlerMapping
빈 (및 기타 여러 가지)을 등록합니다. 그러나 HandlerMapping
핸들러 없이는별로 유용하지 않습니다. RequestMappingHandlerMapping
일부 @Controller
빈을 예상 하므로 @Bean
Java 구성의 메서드 또는 <bean>
XML 구성의 선언을 통해 또는 @Controller
둘 중 하나에서 주석 이 달린 클래스 의 구성 요소 스캔을 통해이를 선언 해야합니다. 이 콩이 있는지 확인하십시오.
경고 메시지와 404가 표시되고 위의 모든 사항을 올바르게 구성한 경우 감지 된 주석 처리기 메서드에서 처리하지 않는 잘못된 URI로 요청을 보내는 것@RequestMapping
입니다.
spring-webmvc
라이브러리 이벤트 다른 내장 HandlerMapping
구현. 예 : BeanNameUrlHandlerMapping
지도
URL에서 슬래시 ( "/")로 시작하는 이름을 가진 Bean으로
언제든지 직접 작성할 수 있습니다. 분명히, 당신이 보내는 요청이 등록 된 HandlerMapping
객체의 핸들러 중 적어도 하나와 일치하는지 확인해야합니다 .
암시 적 또는 명시 적으로 등록하지 당신이 경우 HandlerMapping
콩 (또는 경우 detectAllHandlerMappings
이다 true
)의 DispatcherServlet
레지스터 일부 기본값을 . 이들은 클래스 DispatcherServlet.properties
와 동일한 패키지에 정의되어 DispatcherServlet
있습니다. 그들은이다 BeanNameUrlHandlerMapping
와 DefaultAnnotationHandlerMapping
(과 유사하다 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]
inDispatcherServlet
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.
Stop the Tomcat server
Right click the server and select "Clean"
Right click server again and select "Clean Tomcat Work Directory"
'IT TIP' 카테고리의 다른 글
list ()는 list comprehension보다 약간 더 많은 메모리를 사용합니다. (0) | 2020.10.12 |
---|---|
무엇을 (0) | 2020.10.12 |
ropemacs 사용법 튜토리얼 (0) | 2020.10.12 |
PHP 도메인 이름 가져 오기 (0) | 2020.10.12 |
@ Html.Button이 없습니다! (0) | 2020.10.12 |