文档章节

url-pattern导致的SpringMVC404

 往日的时光
发布于 2017/05/11 20:11
字数 764
阅读 168
收藏 0

临时搭建了一个SpringMVC项目,配置了Controller及ViewResolver,部署在tomcat下,启动无错误.结果访问时能进入Controller但是返回view后浏览器报404错误.

	@RequestMapping(value="bookinfo")
	public ModelAndView bookDetail(String writingId) {
		ModelAndView mav = new ModelAndView("book");
		mav.addObject("writingId", writingId);
		
		return mav;
	}
	    <property name="viewResolvers">
	        <list>
	            <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
	            	<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
	                <property name="prefix" value="/WEB-INF/jsp/"/>
	                <property name="suffix" value=".jsp"/>
	            </bean>
	        </list>
	    </property>

页面/WEB-INF/jsp/book.jsp是真实存在的.

折腾了一下午,终于在google搜索到的一片文章中找到了答案.原文地址:http://www.itwendao.com/article/detail/382888.html

造成404的原因是在web.xml中servlet的url-pattern配置为了'/*','/*'会拦截*.jsp, *.jspx的请求, 使用这种配置最终要转发到一个JSP页面,仍然会由DispatcherServlet, 解析jsp地址, 不能根据jsp页面找到handler, 结果报错.

对照tomcat的日志可以证明上述结论

 RequestMappingHandlerMapping.getHandlerInternal(310) | Looking up handler method for path /book/1
 RequestMappingHandlerMapping.getHandlerInternal(317) | Returning handler method [public java.lang.String com.chineseall.dams.redis.controller.BookController.bookInfo(java.lang.String)]
 DefaultListableBeanFactory.doGetBean(251) | Returning cached instance of singleton bean 'bookController'
 DispatcherServlet.doDispatch(951) | Last-Modified value for [/redis/book/1] is: -1
 ContentNegotiatingViewResolver.getMediaTypes(263) | Requested media types are [text/html, application/xhtml+xml, image/webp, application/xml;q=0.9, */*;q=0.8] based on Accept header types and producible media types [*/*])
 BeanNameViewResolver.resolveViewName(74) | No matching bean found for view name 'book'
 BeanNameViewResolver.resolveViewName(74) | No matching bean found for view name 'book.html'
 DefaultListableBeanFactory.invokeInitMethods(1670) | Invoking afterPropertiesSet() on bean with name 'book'
 DefaultListableBeanFactory.invokeInitMethods(1670) | Invoking afterPropertiesSet() on bean with name 'book.html'
 ContentNegotiatingViewResolver.getBestView(338) | Returning [org.springframework.web.servlet.view.JstlView: name 'book'; URL [/WEB-INF/jsp/book.jsp]] based on requested media type 'text/html'
 DispatcherServlet.render(1276) | Rendering view [org.springframework.web.servlet.view.JstlView: name 'book'; URL [/WEB-INF/jsp/book.jsp]] in DispatcherServlet with name 'redis'
 JstlView.exposeModelAsRequestAttributes(432) | Added model object 'writingId' of type [java.lang.String] to request in view with name 'book'
 JstlView.renderMergedOutputModel(166) | Forwarding to resource [/WEB-INF/jsp/book.jsp] in InternalResourceView 'book'
 DispatcherServlet.doService(865) | DispatcherServlet with name 'redis' processing GET request for [/redis/WEB-INF/jsp/book.jsp]
 RequestMappingHandlerMapping.getHandlerInternal(310) | Looking up handler method for path /WEB-INF/jsp/book.jsp
 RequestMappingHandlerMapping.getHandlerInternal(320) | Did not find handler method for [/WEB-INF/jsp/book.jsp]
 PageNotFound.noHandlerFound(1172) | No mapping found for HTTP request with URI [/redis/WEB-INF/jsp/book.jsp] in DispatcherServlet with name 'redis'
 DispatcherServlet.processRequest(1000) | Successfully completed request
 DispatcherServlet.processRequest(1000) | Successfully completed request

将url-pattern改为'/'后问题解决.

DispatcherServlet配置为’/’, 为什么不拦截*.jsp, *.jspx.的请求?

前面说的当DispatcherServlet配置为'/', 将会覆盖default servlet将会处理所有其他Servlet都不处理的访问请求. 所以这里不拦截拦截.jsp, .jspx.的请求, 一定有其他地方拦截了该请求, 但是仔细查找web.xml并没有发现其他的servlet啊!那一定是在容器中定义的啦~ 
果不其然, 在%TOMCAT_HOME%/conf/web.xml中继承过来的JspServlet会处理该请求.

    <servlet>
        <servlet-name>jsp</servlet-name>
        <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
        <init-param>
            <param-name>fork</param-name>
            <param-value>false</param-value>
        </init-param>
        <init-param>
            <param-name>xpoweredBy</param-name>
            <param-value>false</param-value>
        </init-param>
        <load-on-startup>3</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>jsp</servlet-name>
        <url-pattern>*.jsp</url-pattern>
        <url-pattern>*.jspx</url-pattern>
    </servlet-mapping>

从该web.xml也看到DefaultServlet的定义了(文件中总共就定义了这两个servlet)

     <servlet>
        <servlet-name>default</servlet-name>
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
        <init-param>
           <param-name>debug</param-name>
           <param-value>0</param-value>
        </init-param>
        <init-param>
           <param-name>listings</param-name>
           <param-value>false</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
       <servlet-name>default</servlet-name>
       <url-pattern>/</url-pattern>
    </servlet-mapping>

这也就是为什么我们直接访问不在WEB-INF的jsp, 可以直接找到并解析的原因了. 
我们将test.jsp拷贝一份到webapp下, 直接访问/test.jsp, 访问到jsp中的内容了.并未出现404, 从而验证了我们的猜想.

 

附url-pattern写法解析:http://blog.csdn.net/farawaywl/article/details/52902902

© 著作权归作者所有

粉丝 0
博文 2
码字总数 764
作品 0
私信 提问
springmvc中url-url-pattern /和/*的区别

在使用springmvc时,都会在web.xml中配置一个dispatchservlet,如下: <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener......

有资本再款
2015/12/08
466
0
SpringMVC出现中文乱码解决方法

在web.xml中配置 <!-- 配置字符集 --><filter><filter-name>encodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-par......

snail-
2015/09/09
1K
0
web.xml中servlet的url匹配问题 /和/*的区别 静态资源映射相关

其中/和/*的区别: < url-pattern > / 不会匹配到*.jsp,即:*.jsp不会进入spring的 DispatcherServlet类 。 < url-pattern > /* 会匹配*.jsp,会出现返回jsp视图时再次进入spring的Dispatc......

看见一座山
2018/01/19
773
1
spring MVC的困惑--url-pattern的/和/*有区别

上述问题我也遇到,所以就记录下来。 总是现象就是: spring用到forward("/WEB-INF/jsp/.jsp") 而forward当然是又要经过web.xml的映射的, 然后,在URL匹配时, < url-pattern > / </ url-p......

整俩硬菜
2012/11/07
0
0
druid设置了principalSessionName导致shiro执行logout的时候提示session不存在

@wenshao 你好,想跟你请教个问题: druid设置了principalSessionName导致shiro执行logout的时候提示session不存在 web.xml: shiro org.apache.shiro.web.servlet.ShiroFilter shiro /* Dr......

小草一号
2015/01/19
1K
1

没有更多内容

加载失败,请刷新页面

加载更多

Jenkins系列_插件安装及报错处理

进入Jenkins之后我们可以进行插件的安装,插件管理位于以下模块: 发现上面报了一堆错误,是因为插件的依赖没有安装好,那么这一节,就先把这些错误解决掉吧。解决完成后,也就基本会使用插件...

shzwork
今天
2
0
mysql mysql的所有查询语句和聚合函数(整理一下,忘记了可以随时看看)

查询所有字段 select * from 表名; 查询自定字段 select 字段名 from 表名; 查询指定数据 select * from 表名 where 条件; 带关键字IN的查询 select * from 表名 where 条件 [not] in(元素...

edison_kwok
昨天
9
0
多线程同时加载缓存实现

import com.google.common.cache.Cache;import com.google.common.cache.CacheBuilder;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorServi......

暗中观察
昨天
3
0
利用VisualVM 内存查看

准备工作,建几个测试类。等下就是要查看这几个类里面的属性 package visualvm;public class MultiObject { private String str; private int i; MultiObject(String str...

冷基
昨天
2
0
组装一台工作游戏两用机

一、配置清单如下: 分类 项目 价格(元) 主板 华硕(ASUS)TUF Z370-PLUS GAMING II 电竞特工 Z370二代 支持9代CPU 1049 CPU 英特尔(Intel) i7 8700K 酷睿六核 盒装CPU处理器 2640 风扇 九...

mbzhong
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部