日期:2014-05-16  浏览次数:20401 次

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的名字 --