※. 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>
※ 1) 拦截所有请求
此处需要特别强调的是 <url-pattern>/</url-pattern>使用的是/,而不是/*,如果使用/*,那么请求时可以通过DispatcherServlet转发到相应的Controller中,但是Controller返回的时候,如返回的jsp还会再次被拦截,这样导致404错误,即访问不到jsp。
例:web.xml
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<!-- /* 能处理浏览器的请求,但是会对返回的资源
(XX.jsp等)
进行再一次拦截(页面获取不到内容)。
/表示对页面不处理 html jsp,但是像静态的资源
(xx.js,xxx.css,xxx.png,xxx.jpg)
也会被拦截 -->
<url-pattern>/</url-pattern>
</servlet-mapping>
静态资源:
1.css文件
div{
width: 100px;
height: 100px;
border: 1px solid red;
background-color: blue;
}
2.js文件
function test(){
alert("111");
}
3.图片.images(.png)
hello.jsp页面返回
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<base href="<%=basePath %>">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
<!--引入js用script标签,引入时(src指向地址)里面就不能再写js代码了,需重新构建script标签-->
<script type="text/javascript" src="js/test.js">
</script>
<link type="text/css" rel="stylesheet" href="css/test.css">
</head>
<body>
<!--onclick 鼠标左键点击事件
test() 函数或方法
-->
<div onclick="test()"></div>
success:${name}
<br>
<img src="images/1.png">
</body>
</html>
此时图片,css,js都会被拦截
※ 2) 自定义拦截请求
拦截*.do、*.html、*.action, 例如/user/add.do
这是最传统的方式,最简单也最实用。不会导致静态文件(jpg,js,css)被拦截。
例:web.xml
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<!-- /* 能处理浏览器的请求,但是会对返回的资源
(XX.jsp等)
进行再一次拦截(页面获取不到内容)。
/表示对页面不处理 html jsp,但是像静态的资源
(xx.js,xxx.css,xxx.png,xxx.jpg)
也会被拦截 -->
<!-- 所有需要java类处理的资源名称,都加后缀.do-->
<url-pattern>*.do</url-pattern>
</servlet-mapping>
拦截/,例如:/user/add
可以实现REST风格的访问
普通资源拼接风格:login?name=lisi&passwd=123
REST风格:login/name/lisi/passwd/123
弊端:会导致静态文件(jpg,js,css)被拦截后不能正常显示。
拦截/*,这是一个错误的方式,请求可以走到Controller中,但跳转到jsp时再次被拦截,不能访问到jsp。
※ 3) 静态资源的访问,如jpg,js,css
如果DispatcherServlet拦截"*.do"这样的有后缀的URL,就不存在访问不到静态资源的问题。
如果DispatcherServlet拦截"/",为了实现REST风格,拦截了所有的请求,那么同时对*.js,*.jpg等静态文件的访问也就被拦截了。
例如:
<link href="css/hello.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="js/hello.js"></script>
<img alt="none" src="images/logo.png">
※ 解决方式一:利用Tomcat的defaultServlet来处理静态文件
放在前端控制器前面:
<!-- 让tomcat中的default对静态的资源进行处理
(前端控制器不在拦截),有多少静态资源配置多
少个,还和tomcat的版本有关系 -->
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.png</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的前面(和tomcat版本有关),让defaultServlet先拦截请求,
这样请求就不会进入Spring了
3. 高性能。
※ 解决方式二: 使用<mvc:resources>标签
例如:
<mvc:resources mapping="/images/**" location="/images/"/>
<mvc:resources mapping="/js/**" location="/js/"/>
<mvc:resources mapping="/css/**" location="/css/"/>
mapping: 映射
两个*,表示映射指定路径下所有的URL,包括子路径
location:本地资源路径
这样如果有访问/images或者/js或者/css路径下面的资源的时候,spring就不会拦截了
※ 解决方式三: 使用<mvc:default-servlet-handler/>标签
在spring配置文件中加入此标签配置即可(不提倡用,因为不能看出那些是静态资源)
例:spring.xml文件
<!-- 处理忽略静态的资源
imgaes/* 对应的如 images/1.png 匹配不了images/test/1.png
一个*表示后面跟的是具体资源的名字,不能再有/
imgaes/** 匹配images下的所有资源 images/1.png
images/test/1.png
mapping指向拦截的资源名字匹配
location表示资源存储的位置
/images/ eg:WebContent下的images文件下的内容
-->
<!-- <mvc:resources mapping="/images/**" location="/images/"/>
<mvc:resources mapping="/js/**" location="/js/"/>
<mvc:resources mapping="/css/**" location="/css/"/> -->
<!-- 默认忽略静态资源 -->
<mvc:default-servlet-handler/>
※ .spring提供的编码过滤器
查看这个过滤器类源码便可知这里所传的俩个参数的作用
放在web.xml前端控制器前面(静态资源处理前面)也可以自己写一个servlet拦截器设置编码
<!-- 编码的设置,给request和response设置编码 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
org.springframework.web.filter.CharacterEncodingFilter源码:
public void setForceEncoding(boolean forceEncoding) {
this.forceRequestEncoding = forceEncoding;
this.forceResponseEncoding = forceEncoding;
}
//设置代码编码的方法(拦截器)
@Override
protected void doFilterInternal(
HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
String encoding = getEncoding();
if (encoding != null) {
if (isForceRequestEncoding() || request.getCharacterEncoding() == null) {
request.setCharacterEncoding(encoding);
}
if (isForceResponseEncoding()) {
response.setCharacterEncoding(encoding);
}
}
filterChain.doFilter(request, response);
}