一、<mvc:default-servlet-handler />
web.xml 中的 DispatcherServlet 的配置,使其可以捕获所有的请求:
-
<servlet>
-
-
<servlet-name>springMVC</servlet-name>
-
-
<servlet-
class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
-
-
<load-on-startup>1</load-on-startup>
-
-
</servlet>
-
-
<servlet-mapping>
-
-
<servlet-name>springMVC</servlet-name>
-
-
<url-pattern>/</url-pattern>
-
-
</servlet-mapping>
通过上面url-pattern的配置,所有URL请求都将被Spring MVC的DispatcherServlet截获。
在springMVC-servlet.xml中配置<mvc:default-servlet-handler />后,会在Spring MVC上下文中定义一个org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler,它会像一个检查员,对进入DispatcherServlet的URL进行筛查,如果发现是静态资源的请求,就将该请求转由Web应用服务器默认的Servlet处理,如果不是静态资源的请求,才由DispatcherServlet继续处理。
一般Web应用服务器默认的Servlet名称是"default",因此DefaultServletHttpRequestHandler可以找到它。如果你所有的Web应用服务器的默认Servlet名称不是"default",则需要通过default-servlet-name属性显示指定:
<mvc:default-servlet-handler default-servlet-name="所使用的Web服务器默认使用的Servlet名称" />
二、<mvc:resources />
<mvc:default-servlet-handler />将静态资源的处理经由Spring MVC框架交回Web应用服务器处理。而<mvc:resources />更进一步,由Spring MVC框架自己处理静态资源,并添加一些有用的附加值功能。
首先,<mvc:resources />允许静态资源放在任何地方,如WEB-INF目录下、类路径下等,你甚至可以将JavaScript等静态文件打到JAR包中。通过location属性指定静态资源的位置,由于location属性是Resources类型,因此可以使用诸如"classpath:"等的资源前缀指定资源位置。传统Web容器的静态资源只能放在Web容器的根路径下,<mvc:resources />完全打破了这个限制。
其次,<mvc:resources />依据当前著名的Page Speed、YSlow等浏览器优化原则对静态资源提供优化。你可以通过cacheSeconds属性指定静态资源在浏览器端的缓存时间,一般可将该时间设置为一年,以充分利用浏览器端的缓存。在输出静态资源时,会根据配置设置好响应报文头的Expires和 Cache-Control值。
在接收到静态资源的获取请求时,会检查请求头的Last-Modified值,如果静态资源没有发生变化,则直接返回303相应状态码,提示客户端使用浏览器缓存的数据,而非将静态资源的内容输出到客户端,以充分节省带宽,提高程序性能。
在springMVC-servlet中添加如下配置:
<mvc:resourceslocation="/,classpath:/META-INF/publicResources/" mapping="/resources/**"/>
以上配置将Web根路径"/"及类路径下/META-INF/publicResources/ 的目录映射为/resources路径。假设Web根路径下拥有images、js这两个资源目录,在images下面有bg.gif图片,在js下面有test.js文件,则可以通过/resources/images/bg.gif 和/resources/js/test.js 访问这二个静态资源。
假设WebRoot还拥有images/bg1.gif及 js/test1.js,则也可以在网页中通过/resources/images/bg1.gif 及/resources/js/test1.js 进行引用。
三、<mvc:interceptors>
Xml代码
-
<mvc:interceptors>
-
-
<!-- 使用bean定义一个Interceptor,直接定义在mvc:interceptors根下面的Interceptor将拦截所有的请求 -->
-
-
<bean class="com.host.app.web.interceptor.AllInterceptor"/>
-
-
<mvc:interceptor>
-
-
<mvc:mapping path="/test/number.do"/>
-
-
<!-- 定义在mvc:interceptor下面的表示是对特定的请求才进行拦截的 -->
-
-
<bean class="com.host.app.web.interceptor.LoginInterceptor"/>
-
-
</mvc:interceptor>
-
-
</mvc:interceptors>
由上面的示例可以看出可以利用mvc:interceptors标签声明一系列的拦截器,然后它们就可以形成一个拦截器链,拦截器的执行顺序是按声明的先后顺序执行的,先声明的拦截器中的preHandle方法会先执行,然而它的postHandle方法和afterCompletion方法却会后执行。
在mvc:interceptors标签下声明interceptor主要有两种方式:
1、直接定义一个Interceptor实现类的bean对象。使用这种方式声明的Interceptor拦截器将会对所有的请求进行拦截。
2、使用mvc:interceptor标签进行声明。使用这种方式进行声明的Interceptor可以通过mvc:mapping子标签来定义需要进行拦截的请求路径。
经过上述两步之后,定义的拦截器就会发生作用对特定的请求进行拦截了。
mapping只能映射某些需要拦截的请求,而exclude-mapping用来排除某些特定的请求映射。当我们需要拦截的请求映射是比较通用的,但是其中又包含了某个特殊的请求是不需要使用该拦截器的时候我们就可以把它定义为exclude-mapping了。比如像下面示例这样,我们定义的拦截器将拦截所有匹配/interceptor/**模式的请求,但是不能拦截请求“/interceptor/b”,因为它定义为了exclude-mapping。当定义了exclude-mapping时,Spring MVC将优先判断一个请求是否在execlude-mapping定义的范围内,如果在则不进行拦截。
Xml代码
-
<mvc:interceptors>
-
-
<mvc:interceptor>
-
-
<mvc:mapping path="/interceptor/**" />
-
-
<mvc:exclude-mapping path="/interceptor/b" />
<!-- 不匹配的 -->
-
-
<bean class="com.host.app.web.interceptor.MyInterceptor" />
-
-
</mvc:interceptor>
-
-
</mvc:interceptors>
示例中interceptor下面定义的mapping只有一个,但实际上一个interceptor下面定义的mapping和exclude-mapping都是可以有多个的。
另外,exclude-mapping的定义规则和mapping的定义规则是一样的,我们也可以使用一个星号表示任意字符,使用两个星号表示任意层次的任意字符。比如下面这样。
Xml代码
-
<mvc:interceptors>
-
<mvc:interceptor>
-
<mvc:mapping path="/interceptor/**" />
-
<mvc:exclude-mapping path="/interceptor/b/*" />
<!-- 不匹配的 -->
-
<bean class="com.elim.learn.spring.mvc.interceptor.MyInterceptor" />
-
</mvc:interceptor>
-
</mvc:interceptors>
四、<mvc:resources/>
<mvc:resources location="/static/" mapping="/static/**" />
location元素表示webapp目录下的static包下的所有文件;
mapping元素表示以/static开头的所有请求路径,如/static/a 或者/static/a/b;
该配置的作用是:DispatcherServlet不会拦截以/static开头的所有请求路径,并当作静态资源
交由Servlet处理。
五、<mvc:view-controller path=""/>
WEB-INF目录下面的JSP页面,是不能直接使用URL访问到。需要通过转发的方式,而我们一般都是在控制器中做转发映射,对应一些我们不需要其他操作的JSP页面,我们可以使用<mvc:view-controller path=""/>来配置,这样就可以不用再控制器中再去做转发映射
1、没有使用<mvc:view-controller path=""/>
看看success.jsp页面的目录结果
一般我们需要配置一个spring配置文件中配置一个视图解析器
-
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
-
<propertyname="prefix" value="/WEB-INF/"/>
-
<propertyname="suffix" value=".jsp"/>
-
</bean>
然后在配置一个控制器
-
@Controller
-
-
public
class UserController {
-
-
@RequestMapping(
"/toSuccess")
-
-
public String update(){
-
-
return
"success";
-
-
}
-
-
}
这里使用http://localhost:8080/springmvc-1/toSuccess 可以正确得到页面
使用<mvc:view-controller path=""/>
在springmvc配置文件中配置
<mvc:view-controllerpath="/login/success"/>
path是JSP页面相对WEB-INF的路径
使用http://localhost:8080/springmvc-1/login/success来访问,同样可以得到正确页面
再次访问url:http://localhost:8080/springmvc-1/toSuccess。结果出现404错误
也就是说我们配置了<mvc:view-controller path="/login/success"/>后原来通过控制器来映射的url无法访问到页面了。
其实还用一种办法。我们实际开发中通常要在spring配置文件中添加一句代码
<mvc:annotation-driven></mvc:annotation-driven>
添加后再访问http://localhost:8080/springmvc-1/toSuccess,页面就正常。