在Eclipse开发环境下基于Maven的Spring 4.3.18.RELEASE 版本开发一个web项目,并使用Tomcat发布,项目正常启动后,遇到一个请求报404,问题分析总结如下:
1.contextPath是否正确
因为tomcat默认是以项目包的名字为contextPath的,而maven者是以artifactId为名字打一个war包,因此在默认情况下contextPath是"/artifactId"。因此默认情况下正常的访问路径应该是http://localhost:8080/artifactId/***(协议IP以及端口请以自己的为准)。但是有时候我们想让contextPath简洁一些,只是一个/就行,这时候我们需要进行一次配置,请参考博客https://blog.youkuaiyun.com/tony_java_2017/article/details/80742806
2.请求是否符合DispatcherServlet配置的servlet-mapping中的url-pattern
使用Spring WEB MVC开发一个Java Web项目,DispatcherServlet作为一个前端控制器用来接收所有的请求,如果你的请求不能匹配到DispatcherServlet的servlet-mapping中的url-pattern,即使你的请求在Controller中写的是正确的,则依旧会报404。例如:
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.form</url-pattern>
</servlet-mapping>
spring-mvc.xml
<bean name="/info/hi" class="com.pactera.spring.controller.MyServlet"/>
<bean class="org.springframework.web.servlet.handler.SimpleServletHandlerAdapter"/>
MyServlet.java
public class MyServlet extends HttpServlet{
@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp)
{
System.out.println("req....");
}
}
你的请求是http://localhost:8080/artifactId/test/info则始终会报404,这种情况一般也许是你拷贝别人的配置文件,又没来得及修改导致的。
3.url拼写有错误
此种错误较为好排查,不做分析了。
4.HandlerMapping配置错误
HandlerMapping的作用就是帮助我们根据请求找到对应的处理器,假如找不到处理器就会报404错误。
如上<bean name="/info/hi" class="com.pactera.spring.controller.MyServlet"/>的配置,是基于BeanNameUrlHandlerMapping找到处理器的,Spring MVC在应用上下文没有找到开发者自己配置的HandlerMapping时,会给将系统提供的两个默认的HandlerMapping加载到上下文中,/org/springframework/web/servlet/DispatcherServlet.properties文件中配置项
org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,
org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping就是指定的默认HandlerMapping。
每一种处理器的实现必须和HandlerMapping的配置相适应,在找不到HandlerMapping时会报404错误。
org.springframework.web.servlet.DispatcherServlet.noHandlerFound(DispatcherServlet.java:1176): No mapping found for HTTP request with URI [/info/hi] in DispatcherServlet with name ‘springmvc’ ,请看错误报出的源码:
DispatcherServlet中的noHandlerFound方法
/**
* No handler found -> set appropriate HTTP response status.
* @param request current HTTP request
* @param response current HTTP response
* @throws Exception if preparing the response failed
*/
protected void noHandlerFound(HttpServletRequest request, HttpServletResponse response) throws Exception {
if (pageNotFoundLogger.isWarnEnabled()) {
pageNotFoundLogger.warn("No mapping found for HTTP request with URI [" + getRequestUri(request) +
"] in DispatcherServlet with name '" + getServletName() + "'");
}
if (this.throwExceptionIfNoHandlerFound) {
throw new NoHandlerFoundException(request.getMethod(), getRequestUri(request),
new ServletServerHttpRequest(request).getHeaders());
}
else {
response.sendError(HttpServletResponse.SC_NOT_FOUND);
}
}