本文共 2806 字,大约阅读时间需要 9 分钟。
在Eclipse开发环境下基于Maven的Spring 4.3.18.RELEASE 版本开发一个web项目,并使用Tomcat发布,项目正常启动后,遇到一个请求报404,问题分析总结如下:
因为tomcat默认是以项目包的名字为contextPath的,而maven者是以artifactId为名字打一个war包,因此在默认情况下contextPath是"/artifactId"。因此默认情况下正常的访问路径应该是http://localhost:8080/artifactId/***(协议IP以及端口请以自己的为准)。但是有时候我们想让contextPath简洁一些,只是一个/就行,这时候我们需要进行一次配置,请参考博客
使用Spring WEB MVC开发一个Java Web项目,DispatcherServlet作为一个前端控制器用来接收所有的请求,如果你的请求不能匹配到DispatcherServlet的servlet-mapping中的url-pattern,即使你的请求在Controller中写的是正确的,则依旧会报404。例如:
springmvc org.springframework.web.servlet.DispatcherServlet contextConfigLocation classpath:spring-mvc.xml 1 springmvc *.form
spring-mvc.xml
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,这种情况一般也许是你拷贝别人的配置文件,又没来得及修改导致的。
此种错误较为好排查,不做分析了。
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); } }
关于HandlerMapping的使用与源码分析,请参考我的后续博客
转载地址:http://xasqi.baihongyu.com/