`
Josh_Persistence
  • 浏览: 1633271 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类

Spring中拦截/和拦截/*的区别 - 不能访问到返回的JSP - 访问静态资源(jpg,js等)

阅读更多

一、我们都知道在基于Spring的Application中,需要在web.xml中增加下面类似的配置信息:

 

 

<listener>
	<listener-class>
		org.springframework.web.context.ContextLoaderListener
	</listener-class>
</listener>

<!--   Spring MVC Servlet -->

<servlet>
	<servlet-name>servletName</servlet-name>
	<servlet-class>
		org.springframework.web.servlet.DispatcherServlet
	</servlet-class>
	<load-on-startup>1</load-on-startup>
</servlet>

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

 

 

此处需要特别强调的是<url-pattern>/</url-pattern>使用的是/,而不是/*,如果使用/*,那么请求时可以通过DispatcherServlet转发到相应的Action或者Controller中的,但是返回的内容,如返回的jsp还会再次被拦截,这样导致404错误,即访问不到jsp。所以如果以后发现总是有404错误的时候,别忘了check一下<url-pattern>/</url-pattern>的配置是否是/*.

 

二、其实Spring 的Servlet拦截器匹配规则(即<url-pattern>...</url-pattern>)都可以自己定义,例:当映射为@RequestMapping("/user/add")时

 

1、拦截*.do、*.htm, 例如:/user/add.do

这是最传统的方式,最简单也最实用。不会导致静态文件(jpg,js,css)被拦截。

 

2、拦截/,例如:/user/add

可以实现现在很流行的REST风格。很多互联网类型的应用很喜欢这种风格的URL。

弊端:会导致静态文件(jpg,js,css)被拦截后不能正常显示。想实现REST风格,事情就是麻烦一些。后面有解决办法还算简单。

 

 

3、拦截/*,这是一个错误的方式,请求可以走到Action中,但转到jsp时再次被拦截,不能访问到jsp。

 

三、如何访问到静态的文件,如jpg,js,css?

 

如果你的DispatcherServlet拦截"*.do"这样的有后缀的URL,就不存在访问不到静态资源的问题。

如果你的DispatcherServlet拦截"/",为了实现REST风格,拦截了所有的请求,那么同时对*.js,*.jpg等静态文件的访问也就被拦截了。

我们要解决这个问题。

 

 

目的:可以正常访问静态文件,不可以找不到静态文件报404。

 

方案一:激活Tomcat的defaultServlet来处理静态文件

<servlet-mapping>   
    <servlet-name>default</servlet-name>  
    <url-pattern>*.jpg</url-pattern>     
</servlet-mapping>    
<servlet-mapping>       
    <servlet-name>default</servlet-name>    
    <url-pattern>*.js</url-pattern>    
</servlet-mapping>    
<servlet-mapping>        
    <servlet-name>default</servlet-name>       
    <url-pattern>*.css</url-pattern>      
</servlet-mapping>    

 特点:1. 要配置多个,每种文件配置一个。

             2. 要写在DispatcherServlet的前面, 让defaultServlet先拦截请求,这样请求就不会进入Spring了。

             3. 高性能。

备注:

Tomcat, Jetty, JBoss, and GlassFish 自带的默认Servlet的名字 -- "default"
Google App Engine
自带的 默认Servlet的名字 -- "_ah_default"
Resin
自带的 默认Servlet的名字 -- "resin-file"
WebLogic
自带的 默认Servlet的名字  -- "FileServlet"
WebSphere 
自带的 默认Servlet的名字 -- "SimpleFileServlet"

 

方案二: 在spring3.0.4以后版本提供了mvc:resources ,  使用方法:

<!-- 对静态资源文件的访问 -->    
<mvc:resources mapping="/images/**" location="/images/" /> 

 images/**映射到 ResourceHttpRequestHandler进行处理,location指定静态资源的位置.可以是web application根目录下、jar包里面,这样可以把静态资源压缩到jar包中。cache-period 可以使得静态资源进行web cache 

 
如果出现下面的错误,可能是没有配置<mvc:annotation-driven />的原因。
报错WARNING: No mapping found for HTTP request with URI [/mvc/user/findUser/lisi/770] in DispatcherServlet with name 'springMVC'

 

使用<mvc:resources/>元素,把mapping的URI注册到SimpleUrlHandlerMapping的urlMap中,
key为mapping的URI pattern值,而value为ResourceHttpRequestHandler,
这样就巧妙的把对静态资源的访问由HandlerMapping转到ResourceHttpRequestHandler处理并返回,所以就支持classpath目录,jar包内静态资源的访问.
另外需要注意的一点是,不要对SimpleUrlHandlerMapping设置defaultHandler.因为对static uri的defaultHandler就是ResourceHttpRequestHandler,
否则无法处理static resources request.

 

方案三 ,使用<mvc:default-servlet-handler/>

<mvc:default-servlet-handler/> 

 

会把"/**" url,注册到SimpleUrlHandlerMapping的urlMap中,把对静态资源的访问由HandlerMapping转到 org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler 处理并返回.
DefaultServletHttpRequestHandler使用就是各个Servlet容器自己的默认Servlet.

 

 

补充说明:多个HandlerMapping的执行顺序问题:

DefaultAnnotationHandlerMapping的order属性值是:0

<mvc:resources/ >自动注册的 SimpleUrlHandlerMapping的order属性值是: 2147483646

 

<mvc:default-servlet-handler/>自动注册 的SimpleUrlHandlerMapping 的order属性值是: 2147483647

 

 

spring会先执行order值比较小的。当访问一个a.jpg图片文件时,先通过 DefaultAnnotationHandlerMapping 来找处理器,一定是找不到的,因为我们没有叫a.jpg的Action。然后再按order值升序找,由于最后一个 SimpleUrlHandlerMapping 是匹配 "/**"的,所以一定会匹配上,就可以响应图片。

最后再说明一下,方案二、方案三 在访问静态资源时,如果有匹配的(近似)总拦截器,就会走拦截器。如果你在拦截中实现权限检查,要注意过滤这些对静态文件的请求。

 

如果你的DispatcherServlet拦截 *.do这样的URL后缀,就不存上述问题了。还是有后缀方便。

 

6
4
分享到:
评论
4 楼 Josh_Persistence 2013-08-09  
没错,用<mvc:default-servlet-handler />是可以的,相当于用默认的Servlet来处理静态页面。
3 楼 七月这天 2013-08-09  
七月这天 写道
我们的项目中用的是/*的配置,都能正常访问啊,是因为我们用的velocity吗?

研究了下  加上<mvc:default-servlet-handler />就ok了,用/*的配置就不会有404错误了!
2 楼 七月这天 2013-08-09  
我们的项目中用的是/*的配置,都能正常访问啊,是因为我们用的velocity吗?
1 楼 lvwenwen 2013-08-09  
写得不错!

相关推荐

    拦截器和控制器的区别

    拦截器和过滤器的区别 1、拦截器基于动态代理 , 过滤器基于函数回调 2、拦截器不依赖于servlet容器,通过动态代理实现,过滤器依赖于servlet容器 3、拦截器在方法前后,异常前后等调用,而过滤器只能在请求前和请求...

    security第三版

    login没设置拦截...accessDeny是权限不足返回的页面.. 这里本来想统筹spring mvc...但是为了体现security,就直接使用jsp来替代了... 主要的代码在于 : util.security包..以及spring-security.xml配置文件

    Spring-Reference_zh_CN(Spring中文参考手册)

    12.2.4. 不使用回调的基于Spring的DAO实现 12.2.5. 基于Hibernate3的原生API实现DAO 12.2.6. 编程式的事务划分 12.2.7. 声明式的事务划分 12.2.8. 事务管理策略 12.2.9. 容器资源 vs 本地资源 12.2.10. 在应用服务器...

    java三大框架注解配置

    修改struts默认的拦截: &lt;filter-mapping&gt; &lt;filter-name&gt;struts2&lt;/filter-name&gt; &lt;url-pattern&gt;*.action&lt;/url-pattern&gt; &lt;url-pattern&gt;*.jsp&lt;/url-pattern&gt; &lt;/filter-mapping&gt; 2、添加hibernate功能 3、添加...

    Java项目:诚途旅游系统(java+JSP+Spring+SSM+Mysql)

    包括网站展示和后台管理功能,网站主要是页面浏览以及评论、制定旅游方案、智能推荐功能 后台就是维护网站展示的内容,添加旅游景点、管理用户、查看用户的搜索记录功能 运行环境: 1、maven 2、jkd1.7 3、eclipse...

    shiroFilter权限验证

    所以我们在web.xml中配置shiros的过滤拦截。正常情况下,我们需要将shiro的filter配置在所有的filter前面,当然和encodingFilter这个filter是不区分前后的。因为两者互相不影响的。spring-shiro.xml 这里我们将来看...

    springmybatis

    3. 在session 中完成对数据的增删改查和事务提交等. 4. 在用完之后关闭session 。 5. 在java 对象和 数据库之间有做mapping 的配置文件,也通常是xml 文件。 mybatis实战教程(mybatis in action)之一:开发环境搭建 ...

    基于SSM框架+mysql实现客户管理系统源码+项目说明.zip

    Web表现层:该层主要包括Spring MVC中的Controller类和JSP页面。Controller类主要负责拦截用户请求,并调用业务逻辑层中相应组件的业务逻辑方法来处理用户请求,然后将相应的结果返回给JSP页面。 ![Image ...

    Spring中文帮助文档

    12.2.4. 不使用回调的基于Spring的DAO实现 12.2.5. 基于Hibernate3的原生API实现DAO 12.2.6. 编程式的事务划分 12.2.7. 声明式的事务划分 12.2.8. 事务管理策略 12.2.9. 容器资源 vs 本地资源 12.2.10. 在应用...

    基于 Spring Boot +mysql的学生宿舍管理系统源代码+数据库

    前端方面使用了 jsp、Bootstrap 和 layui 等框架。系统还使用拦截器实现了登录验证和基于 RBAC 模型的权限管理。 技术栈 后端:Spring Boot、Spring MVC、MySQL、Maven、MyBatis 前端:jsp、Bootstrap、layui 修改...

    从零开始学Spring Boot

    1.4 Spring Boot返回json数据 1.5 Spring Boot热部署 1.6 Spring Boot使用别的json解析框架 1.7 全局异常捕捉 1.8 Spring Boot datasource - mysql 1.9 JPA - Hibernate 1.10 使用JPA保存数据 1.11 使用JdbcTemplate...

    Spring+jsp老项目转Springboot的示例Demo

    指导如何将Spring+jsp老项目转Springboot的示例Demo,是以最小化配置方式,访问每个页面不需要经过控制层解释,只需要配置一个JspServlet拦截所有Jsp页面即可。

    Spring Security-3.0.1中文官方文档(翻译版)

    Spring Security-3.0.1 中文官方文档(翻译版) 这次发布的Spring Security-3.0.1 是一个bug fix 版,主要是对3.0 中存在的一些问题进 行修 正。文档中没有添加新功能的介绍,但是将之前拼写错误的一些类名进行...

    spring security 参考手册中文版

    Spring Security 参考 1 第一部分前言 15 1.入门 16 2.介绍 17 2.1什么是Spring Security? 17 2.2历史 19 2.3版本编号 20 2.4获得Spring安全 21 2.4.1使用Maven 21 Maven仓库 21 Spring框架 22 2.4.2 Gradle 23 ...

    SpringBoot 学习笔记+完整教程

    * 静态资源处理 * 实现任务调度 * 普通类调用 Bean * 使用模板引擎 * 集成 JSP * 集成 servlet * 集成 Fliter 和 Linstener * 拦截器 HandlerInterceptor * 系统启动任务 CommandLineRunner * 集成 Junit 单元测试 *...

    spring boot 实践学习案例,与其它组件整合

    spring boot 实践学习案例,与其它组件结合如 mybatis、jpa、dubbo、redis、mongodb、memcached、kafka、rabbitmq、activemq、elasticsearch、security、shiro等 #### Spring Boot 版本 - 2.0.3.RELEASE #### 模块...

    Spring Security 中文教程.pdf

    5.5. Spring Security中的访问控制(验证) 5.5.1. 安全和AOP建议 5.5.2. 安全对象和AbstractSecurityInterceptor 5.5.2.1. 配置属性是什么? 5.5.2.2. RunAsManager 5.5.2.3. AfterInvocationManager ...

    spring chm文档

    Spring Framework 开发参考手册 Rod Johnson Juergen Hoeller Alef Arendsen Colin Sampaleanu Rob Harrop Thomas Risberg Darren Davison Dmitriy Kopylenko Mark Pollack Thierry Templier Erwin ...

Global site tag (gtag.js) - Google Analytics