SpringMVC,3种不一样的URL路由配置方法(这根本不是一个小问题)(转)

SpringMVC中配置URL拦截,很是简单。网上找个示例,就能经过。可是,在我作了好几个Web项目,又参与了别人主导的Web项目时,发现URL配置也很是有学问。css

1. 先说说一种比较常见的:html

   

<servlet>java

<servlet-name>theDispatcher</servlet-name>web

<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>正则表达式

<init-param>spring

<param-name>contextConfigLocation</param-name>spring-mvc

<param-value>classpath:spring/spring-mvc-servlet.xml</param-value>服务器

</init-param>mvc

<load-on-startup>1</load-on-startup>app

</servlet>

<servlet-mapping>

<servlet-name>theDispatcher</servlet-name>

<url-pattern>*.html</url-pattern>

</servlet-mapping>

 

让SpringMVC指拦截 动态请求,js、css、img等静态资源不通过Spring,直接让Web容器处理。

 

若是配置了拦截器,也只会拦截.html动态请求。

 

静态资源不走Spring,也不走拦截器,性能固然是比较好的。

若是使用了Nginx,配置静态资源拦截,让Nginx处理静态资源的访问。由于Nginx在处理静态资源方面,比Tomcat等Web容器要强。

缺点:这种拦截动态请求的方法,比较死板。

2.  我本身常常有一种需求, http://FansUnion.cn/news 这种不指定.html后缀的其实也是 动态请求,因此我在配置url-pattern喜欢用“/”,即拦截全部的请求。URL是能够灵活配置了,问题又来了,静态资源再也不由Tomcat处理,因此必须在SpringMVC中再次配置,

 

<mvc:resources mapping="/static/**" location="/static/" />

让SpringMVC把static静态资源也处理了。显然,让SpringMVC处理静态资源的性能没有Tomcat直接处理比较高。

理论上,请求中转的次数越多, 性能越差。

本觉得万事大吉,虽然静态资源的性能较低,至少程序能够正常运行了,“反正是混过去了”。

进一步的需求,若是在Spring中配置了登陆等拦截器,这个时候也会把 静态资源给拦截进来。

 

 

 

<mvc:resources mapping="/static/**" location="/static/" /> 这种URL映射,也没法逃脱拦截器的魔爪。

 

 

我是怎么发现这个问题的呢?

public class BaseLoginInterceptor extends HandlerInterceptorAdapter {

 

public boolean preHandle(HttpServletRequest request,

HttpServletResponse response, Object handler) throws Exception {

LoginUtil.setCurrentUser(null);

initCurrentUser(request, response);

HandlerMethod handlerMethod = (HandlerMethod) handler;

} 

公司的项目,Boss的登陆拦截器配置如上,“ HandlerMethod handlerMethod = (HandlerMethod) handler;

”。可是我在本身的项目中,发现这行代码是有问题的。若是静态资源被拦截到,会报错:

java.lang.ClassCastException: org.springframework.web.servlet.resource.ResourceHttpRequestHandler cannot be cast to org.springframework.web.method.HandlerMethod

经过异常能够发现,  Object handler是 ResourceHttpRequestHandler  ,而不是

HandlerMethod。

由于 

mvc:resources把静态资源请求交给了 ResourceHttpRequestHandler

 

处理,所以强制转换是有问题的。

 

公司项目中Boss的配置之因此没有出现问题,是由于他配置的是只拦截“.html” 动态请求,因此强制转换老是成立的。

 

---------------------------------------------

咱们分析了上述两种状况, 发现“根本矛盾”“根本需求”是啥?

 

1.动态请求的URL应该很是灵活,/news /news.html都应该算做动态请求。

2.SpringMVC的url-pattern能够配置 / , *.html,或者正则表达式,可是我不太喜欢用正则表达式。

3.若是可能,SpringMVC最好不要拦截静态资源,让Tomcat容器直接处理更好。

 

 

 

 

<mvc:resources mapping="/static/**" location="/static/" />

 

这是为了性能考虑。

4.若是线上服务器配置了Nginx,我能够选择让Nginx拦截静态请求,由于比Tomcat处理性能更高。

 

本地是否配置Nginx,都不须要改动任何代码。

-------------------------------------------------

上面说的 第一种方法的缺陷是,url配置不够灵活。

 

第二种方法的缺陷是,SpringMVC要拦截静态资源,并且登陆拦截器 也会拦截 静态资源,不但性能差,程序还得再次修改,判断HandlerMethod的实际类型。

 

3.终极解决方案: 

 

以我习惯用的第2种方法为基础,进一步改进:

去掉

 

 

 

 

 

 

<mvc:resources mapping="/static/**" location="/static/" />,不作静态资源请求的映射。

在web.xml里增长以下配置:

 

<servlet-mapping>

<servlet-name>default</servlet-name>

<url-pattern>/static/*</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>

激活Tomcat的defaultServlet来处理静态文件。
相关文章
相关标签/搜索