SpringMVC基础学习笔记 视频:尚硅谷  学习时间:2022年1月14日
1 SpringMVC简介 1.1 什么是MVC MVC是一种软件架构的思想,将软件按照模型、视图、控制器来划分
M:Model,模型层,指工程中的JavaBean,作用是处理数据。JavaBean分为两类: 
 
一类称为实体类Bean:专门存储业务数据的,如 Student、User 等 
一类称为业务处理 Bean:指 Service 或 Dao 对象,专门用于处理业务逻辑和数据访问。 
 
V:View,视图层,指工程中的html或jsp等页面,作用是与用户进行交互,展示数据
 
C:Controller,控制层,指工程中的servlet,作用是接收请求和响应浏览器
 
 
MVC的工作流程
 
用户通过视图层发送请求到服务器,在服务器中请求被Controller接收,Controller调用相应的Model层处理请求,处理完毕将结果返回到Controller,Controller再根据请求处理的结果找到相应的View视图,渲染数据后最终响应给浏览器。
1.2 什么是SpringMVC SpringMVC是Spring的一个后续产品,是Spring的一个子项目
SpringMVC 是 Spring 为表述层开发提供的一整套完备的解决方案。在表述层框架历经 Strust、WebWork、Strust2 等诸多产品的历代更迭之后,目前业界普遍选择了 SpringMVC 作为 Java EE 项目表述层开发的首选方案 。
注:三层架构分为表述层(或表示层)、业务逻辑层、数据访问层,表述层表示前台页面和后台servlet
1.3 SpringMVC的特点 
Spring 家族原生产品 ,与 IOC 容器等基础设施无缝对接 
基于原生的Servlet ,通过了功能强大的前端控制器DispatcherServlet ,对请求和响应进行统一处理 
表述层各细分领域需要解决的问题全方位覆盖 ,提供全面解决方案  
代码清新简洁 ,大幅度提升开发效率 
内部组件化程度高,可插拔式组件即插即用 ,想要什么功能配置相应组件即可 
性能卓著 ,尤其适合现代大型、超大型互联网项目要求 
 
2 入门案例 2.1 创建maven工程 
maven工程的archetype选择webapp
 
工程架构: 
 
打包方式为war: 
 
引入相关依赖: 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 <dependencies >          <dependency >          <groupId > org.springframework</groupId >          <artifactId > spring-webmvc</artifactId >          <version > 5.3.1</version >      </dependency >           <dependency >          <groupId > ch.qos.logback</groupId >          <artifactId > logback-classic</artifactId >          <version > 1.2.3</version >      </dependency >           <dependency >          <groupId > javax.servlet</groupId >          <artifactId > javax.servlet-api</artifactId >          <version > 3.1.0</version >          <scope > provided</scope >      </dependency >           <dependency >          <groupId > org.thymeleaf</groupId >          <artifactId > thymeleaf-spring5</artifactId >          <version > 3.0.12.RELEASE</version >      </dependency >  </dependencies > 
 
注:由于 Maven 的传递性,我们不必将所有需要的包全部配置依赖,而是配置最顶端的依赖,其他靠传递性导入。
2.2 配置web.xml 注册SpringMVC的前端控制器DispatcherServlet
2.2.1 默认配置方式 此配置作用下,SpringMVC的配置文件默认位于WEB-INF下,默认名称为\-servlet.xml,例如,以下配置所对应SpringMVC的配置文件位于WEB-INF下,文件名为springMVC-servlet.xml 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <web-app >   <display-name > Archetype Created Web Application</display-name >       <servlet >      <servlet-name > springMVC</servlet-name >      <servlet-class > org.springframework.web.servlet.DispatcherServlet</servlet-class >    </servlet >    <servlet-mapping >      <servlet-name > springMVC</servlet-name >           <url-pattern > /</url-pattern >    </servlet-mapping >  </web-app > 
 
2.2.2 扩展配置方式 可通过init-param标签设置SpringMVC配置文件的位置和名称,通过load-on-startup标签设置SpringMVC前端控制器DispatcherServlet的初始化时间,将其提前到服务器启动时就初始化前端控制器。
在resource下创建一个spring配置文件springMVC.xml: 
 
web.xml代码:指定SpringMVC配置文件的位置和名称 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 <web-app >   <display-name > Archetype Created Web Application</display-name >       <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:springMVC.xml</param-value >      </init-param >           <load-on-startup > 1</load-on-startup >    </servlet >    <servlet-mapping >      <servlet-name > springMVC</servlet-name >           <url-pattern > /</url-pattern >    </servlet-mapping >  </web-app > 
 
<url-pattern>标签中使用/和/*的区别:
 
/所匹配的请求可以是/login或.html或.js或.css方式的请求路径,但是/不能匹配.jsp请求路径的请求 。因此就可以避免在访问jsp页面时,该请求被DispatcherServlet处理,从而找不到相应的页面。/*则能够匹配所有请求,例如在使用过滤器时,若需要对所有请求进行过滤,就需要使用/*的写法。
2.3 创建请求控制器 由于前端控制器对浏览器发送的请求进行了统一的处理,但是具体的请求有不同的处理过程,因此需要创建处理具体请求的类,即请求控制器 。
请求控制器中每一个处理请求的方法称为控制器方法 。
因为SpringMVC的控制器由一个POJO(普通的Java类)担任 ,因此需要通过@Controller注解将其标识为一个控制层组件,交给Spring的IoC容器管理,此时SpringMVC才能够识别控制器的存在。
新建包com.hongyi.mvc.controller,并新建类HelloController:
1 2 3 4 @Controller public  class  HelloController   {     } 
 
2.4 创建springMVC的配置文件 
代码如下: 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 <?xml version="1.0" encoding="UTF-8"?> <beans  xmlns ="http://www.springframework.org/schema/beans"         xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"         xmlns:context ="http://www.springframework.org/schema/context"         xmlns:mvc ="http://www.springframework.org/schema/mvc"         xsi:schemaLocation ="http://www.springframework.org/schema/beans         http://www.springframework.org/schema/beans/spring-beans-4.2.xsd     http://www.springframework.org/schema/mvc     http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd     http://www.springframework.org/schema/context     http://www.springframework.org/schema/context/spring-context-4.2.xsd" >         <context:component-scan  base-package ="com.hongyi.mvc.controller" />           <bean  id ="viewResolver"  class ="org.thymeleaf.spring5.view.ThymeleafViewResolver" >          <property  name ="order"  value ="1" />          <property  name ="characterEncoding"  value ="UTF-8" />          <property  name ="templateEngine" >              <bean  class ="org.thymeleaf.spring5.SpringTemplateEngine" >                  <property  name ="templateResolver" >                      <bean  class ="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver" >                                                   <property  name ="prefix"  value ="/WEB-INF/templates/" />                                                   <property  name ="suffix"  value =".html" />                          <property  name ="templateMode"  value ="HTML5" />                          <property  name ="characterEncoding"  value ="UTF-8"  />                      </bean >                  </property >              </bean >          </property >      </bean >  </beans > 
 
在WEB-INF下创建文件夹templates,并新建html文件index.html 
 
2.5 测试HelloWorld 2.5.1 实现对首页的访问 
1 2 3 4 5 6 7 8 9 10 <!DOCTYPE html > <html  lang ="en"  xmlns:th ="http://www.thymeleaf.org" > <head >     <meta  charset ="UTF-8" >      <title > 首页</title >  </head > <body >     <h1 > Hello World!</h1 >  </body > </html > 
 
1 2 3 4 5 6 7 8 9 10 @RequestMapping("/") public  String index ()   {                   return  "index" ; } 
 
部署tomcat服务器:注意版本选择9以下的,版本太高有bug! 
 
执行结果
 
2.5.2 通过超链接跳转到指定页面 在主页index.html中设置超链接:
1 2 3 4 5 6 7 8 9 10 11 <!DOCTYPE html > <html  lang ="en"  xmlns:th ="http://www.thymeleaf.org" > <head >     <meta  charset ="UTF-8" >      <title > 首页</title >  </head > <body >     <h1 > Hello World123!</h1 >      <a  th:href ="@{/target}" > 访问目标页面target.html</a >  </body > </html > 
 
在请求控制器中创建处理请求的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 @Controller public  class  HelloController   {    @RequestMapping("/")      public  String index ()   {                  return  "index" ;     }     @RequestMapping("/target")      public  String toTarget ()   {         return  "target" ;     } } 
 
测试结果
 
2.6 总结 浏览器发送请求,若请求地址符合前端控制器的url-pattern,该请求就会被前端控制器DispatcherServlet处理。前端控制器会读取SpringMVC的核心配置文件springmvc.xml,通过扫描组件找到控制器,将请求地址和控制器中@RequestMapping注解的value属性值进行匹配,若匹配成功,该注解所标识的控制器方法就是处理请求的方法。处理请求的方法需要返回一个字符串类型的视图名称,该视图名称会被视图解析器 解析,加上前缀和后缀组成视图的路径,通过Thymeleaf对视图进行渲染,最终转发到视图所对应页面。
3 @RequestMapping注解 
源码
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented @Mapping public  @interface  RequestMapping {    String name ()  default  "" ;     @AliasFor("path")      String[] value() default  {};     @AliasFor("value")      String[] path() default  {};     RequestMethod[] method() default  {};     String[] params() default  {};     String[] headers() default  {};     String[] consumes() default  {};     String[] produces() default  {}; } 
 
3.1 注解功能 从注解名称上我们可以看到,@RequestMapping注解的作用就是将请求和处理请求的控制器方法 关联起来,建立映射关系。
SpringMVC 接收到指定的请求,就会来找到在映射关系中对应的控制器方法来处理这个请求。
3.2 注解位置 
示例
 
新增一个类RequestMappingController 
 
1 2 3 4 5 6 7 8 @Controller @RequestMapping("/hello") public  class  RequestMappingController   {    @RequestMapping("/testRequestMapping")      public  String success ()   {         return  "success" ;     } } 
 
新增一个html页面success.html: 
 
1 2 3 4 5 6 7 8 9 10 <!DOCTYPE html > <html  lang ="en"  xmlns:th ="http://www.thymeleaf.org" > <head >     <meta  charset ="UTF-8" >      <title > Success</title >  </head > <body > <h1 > Success!</h1 > </body > </html > 
 
修改主页面index.html: 
 
1 2 3 4 5 6 7 8 9 10 11 <!DOCTYPE html > <html  lang ="en"  xmlns:th ="http://www.thymeleaf.org" > <head >     <meta  charset ="UTF-8" >      <title > 首页</title >  </head > <body >     <h1 > Hello World!</h1 >      <a  th:href ="@{/hello/testRequestMapping}" > 测试RequestMapping注解的位置</a > <br >  </body > </html > 
 
测试结果: 
 
3.3 注解属性 3.3.1 value 
@RequestMapping注解的value属性通过请求的请求地址 匹配请求映射 
@RequestMapping注解的value属性是一个字符串类型的数组 ,表示该请求映射能够匹配多个请求地址所对应的请求 
@RequestMapping注解的value属性必须设置 ,至少通过请求地址匹配请求映射 
 
RequestMappingController 
 
1 2 3 4 5 6 7 8 @Controller @RequestMapping("/hello") public  class  RequestMappingController   {    @RequestMapping(value = {"/testRequestMapping", "/testValue"})      public  String success ()   {         return  "success" ;     } } 
 
index.html 
 
1 2 3 <h1 > Hello World!</h1 > <a  th:href ="@{/hello/testRequestMapping}" > 测试value:testRequestMapping</a > <br > <a  th:href ="@{/hello/testValue}" > 测试value:testValue</a > <br > 
 
测试结果: 
 
3.3.2 method 
@RequestMapping注解的method属性通过请求的请求方式 (get或post)匹配请求映射 
@RequestMapping注解的method属性是一个RequestMethod类型的数组 ,表示该请求映射能够匹配多种请求方式的请求 
若当前请求的请求地址满足请求映射的value属性,但是请求方式不满足method属性,则浏览器报错405:Request method ‘POST’ not supported,即两个属性要求均要满足  
 
正常示例
 
RequestMappingController 
 
1 2 3 4 5 6 7 8 9 10 11 @Controller @RequestMapping("/hello") public  class  RequestMappingController   {    @RequestMapping(              value = {"/testRequestMapping", "/testValue"},             method = {RequestMethod.GET, RequestMethod.POST}     )     public  String success ()   {         return  "success" ;     } } 
 
index.html 
 
1 2 3 4 5 <h1 > Hello World!</h1 > <a  th:href ="@{/hello/testValue}" > 测试method属性GET</a > <br > <form  th:action ="@{/hello/testValue}"  method ="post" >     <input  type ="submit"  value ="测试method属性POST" >  </form > 
 
测试结果 
 
异常示例
 
例如删除POST方式后的执行结果:
1 2 3 4 @RequestMapping(         value = {"/testRequestMapping", "/testValue"},         method = RequestMethod.GET ) 
 
结合请求方式的派生注解
 
对于处理指定请求方式的控制器方法,SpringMVC中提供了@RequestMapping的派生注解 
 
示例:
1 2 3 4 @GetMapping("/testGetMapping") public  String testGetMapping ()   {    return  "success" ; } 
 
常用的请求方式有get,post,put,delete 
 
但是目前浏览器只支持get和post,若在form表单提交时,为method设置了其他请求方式的字符串(put或delete),则按照默认的请求方式get处理。
若要发送put和delete请求,则需要通过spring提供的过滤器HiddenHttpMethodFilter,在RESTful部分会讲到。
3.3.3 param 
@RequestMapping注解的params属性通过请求的请求参数匹配请求映射 
@RequestMapping注解的params属性是一个字符串类型的数组 ,可以通过四种表达式设置请求参数和请求映射的匹配关系
"param":要求请求映射所匹配的请求必须携带param请求参数     
"!param":要求请求映射所匹配的请求必须不能携带param请求参数 
"param=value":要求请求映射所匹配的请求必须携带param请求参数且param=value 
"param!=value":要求请求映射所匹配的请求必须携带param请求参数但是param!=value 
 
 
 
示例
 
1 2 3 4 5 params = {"username" }  params = {"!username" }  params = {"username=Mark" }  params = {"username!=Mark" } params = {"username=admin" , "password=123456" }  
 
程序示例
 
1 2 3 4 5 6 7 @RequestMapping(     value = "/testParams",     params = {"username=admin", "password=123456"} ) public  String testParams ()   {    return  "success" ; } 
 
1 <a  th:href ="@{/hello/testParams(username='admin', password=123456)}" > 测试params属性</a > 
 
1 <a  th:href ="@{/hello/testParams(username='admin', password=12345678)}" > 测试params属性</a > 
 
若当前请求满足@RequestMapping注解的value和method属性,但是不满足headers属性,此时页面显示404错误,即资源未找到。
3.4 SpringMVC支持ant风格的路径 即SpringMVC支持通配符形式的路径匹配。
?:表示任意的单个字符 
*:表示任意的0个或多个字符 
**:表示任意的一层或多层目录 
 
注意 :在使用*时,只能使用/* /xxx的方式
使用1
 
1 2 3 4 5 @RequestMapping("/a?a/testAnt") public  String testAnt ()   {    return  "success" ; } 
 
1 <a  th:href ="@{/hello/aka/testAnt" > 测试Ant风格的路径</a > 
 
使用2
 
1 2 3 4 5 @RequestMapping("/a*a/testAnt") public  String testAnt ()   {    return  "success" ; } 
 
1 <a  th:href ="@{/hello/abcdefa/testAnt" > 测试Ant风格的路径</a > 
 
使用3
 
1 2 3 4 5 @RequestMapping("/**/testAnt") public  String testAnt ()   {    return  "success" ; } 
 
1 <a  th:href ="@{/hello/aaa/bbb/testAnt" > 测试Ant风格的路径</a > 
 
3.5 SpringMVC支持路径中的占位符 
原始方式:/deleteUser?id=1&username=mark 
rest方式:/deleteUser/1/mark 
 
SpringMVC路径中的占位符常用于RESTful风格中,当请求路径中将某些数据通过路径的方式传输到服务器中,就可以在相应的@RequestMapping注解的value属性中通过占位符{xxx}表示传输的数据,再通过@PathVariable注解,将占位符所表示的数据赋值给控制器方法的形参。
使用
 
1 2 3 4 5 @RequestMapping(value = "/testRest/{id}/{username}") public  String testRest (@PathVariable("id")  String id, @PathVariable("username")  String username)   {    System.out.println("id:"  + id + ",username:"  + username);     return  "success" ; } 
 
1 <a  th:href ="@{/hello/testRest/1/admin}" > 测试路径中的占位符</a > <br > 
 
4 获取请求参数 4.1 通过原生ServleAPI获取 例如将HttpServletRequest作为控制器方法的形参,此时HttpServletRequest类型的参数表示封装了当前请求的请求报文的对象。
新增控制器类TestController.java 
 
1 2 3 4 5 6 7 @Controller public  class  TestController   {    @RequestMapping("/param")      public  String param ()   {         return  "test_param" ;     } } 
 
1 2 3 4 5 6 7 8 9 10 11 <!DOCTYPE html > <html  lang ="en"  xmlns:th ="http://www.thymeleaf.org" > <head >     <meta  charset ="UTF-8" >      <title > 测试请求参数</title >  </head > <body >     <h1 > 测试请求参数</h1 >      <a  th:href ="@{/testServletAPI(username='admin', password='123456')}" > 测试使用servletAPI获取请求参数</a >  </body > </html > 
 
新建控制器类ParamComtroller.java,并新写方法testServletParam 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @Controller public  class  ParamController   {         @RequestMapping("/testServletAPI")      public  String testServletAPI (HttpServletRequest request)   {         String username = request.getParameter("username" );         String password = request.getParameter("password" );         System.out.println("username: "  + username + ", password: "  + password);         return  "success" ;     } } 
 
执行结果:
4.2 通过控制器方法的形参获取请求参数 在控制器方法的形参位置,设置和请求参数同名 的形参,当浏览器发送请求,匹配到请求映射时,在DispatcherServlet中就会将请求参数赋值给相应的形参。
1 <a  th:href ="@{/testServletAPI(username='admin', password='123456')}" > 测试使用控制器形参获取请求参数</a > 
 
1 2 3 4 5 6 7 8 9 10 11 @RequestMapping("/testParam") public  String testParam (String username, String password)   {    System.out.println("username: "  + username + ", password: "  + password);     return  "success" ; } 
 
执行结果:
如果请求参数中出现多个同名参数(例如复选框中提交多个同名数据),可以在形参位置设置一个字符串类型 或者字符串数组类型 来接收此请求参数:
1 2 3 4 5 6 7 8 9 <form  th:action ="@{/testParam}"  method ="post" >     用户名:<input  type ="text"  name ="username" > <br >      密码:<input  type ="password"  name ="password" > <br >      爱好:<input  type ="checkbox"  name ="hobby"  value ="a" > a     <input  type ="checkbox"  name ="hobby"  value ="b" > b     <input  type ="checkbox"  name ="hobby"  value ="c" > c     <br >      <input  type ="submit"  value ="测试使用控制器的形参获取请求参数" >  </form > 
 
1 2 3 4 5 @RequestMapping("/testParam") public  String testParam (String username, String password, String[] hobby)   {    System.out.println("username: "  + username + ", password: "  + password + ", hobby: "  + Arrays.toString(hobby));     return  "success" ; } 
 
执行结果:
注意:
若使用字符串数组类型的形参,此参数的数组中包含了每一个数据 
若使用字符串类型的形参,此参数的值为每个数据中间使用逗号拼接的结果 
 
4.3 @RequestParam注解 
作用:将请求参数和控制器方法的形参创建映射关系 
属性:
value(或name):指定为形参赋值的请求参数(前端请求的)的参数名 
required:设置是否必须传输此请求参数,默认值为true。若设置为true时,则当前请求必须传输value所指定的请求参数,若没有传输该请求参数,且没有设置defaultValue属性,则页面报错400:Required String parameter ‘xxx’ is not present;若设置为false,则当前请求不是必须传输value所指定的请求参数,若没有传输,则注解所标识的形参的值为null 
defaultValue:不管required属性值为true或false,当value所指定的请求参数没有传输或传输的值为””时,则使用默认值为形参赋值 
 
 
 
示例
 
例如,前端的请求参数名称改为user_name:
1 用户名:<input  type ="text"  name ="user_name" > <br >  
 
则后端相应的添加上注解:
1 @RequestParam("user_name")  String username
 
 
可用的完整的形式:
1 @RequestParam(value = "user_name", required = false, defaultValue = "hongyi")  String username
 
1 2 3 4 5 6 7 8 @RequestMapping("/testParam") public  String testParam (         @RequestParam(value = "user_name", required = false, defaultValue = "hongyi")  String username,         String password,         String[] hobby)   {    System.out.println("username: "  + username + ", password: "  + password + ", hobby: "  + Arrays.toString(hobby));     return  "success" ; } 
 
@RequestHeader是将请求头 信息和控制器方法的形参创建映射关系
@RequestHeader注解一共有三个属性:value、required、defaultValue,用法同@RequestParam
示例
 
1 2 3 4 public  String testParam (@RequestHeader("Host")  String host)   {	System.out.println("Host: "  + host);     return  "success" ; } 
 
执行结果:
4.5 @CookieValue @CookieValue是将cookie数据和控制器方法的形参创建映射关系
@CookieValue注解一共有三个属性:value、required、defaultValue,用法同@RequestParam
示例
 
1 2 3 4 5 @RequestMapping("/testParam") public  String testParam (@CookieValue("JSESSIONID")  String cookie)   {    System.out.println("cookie: "  + cookie);     return  "success" ; } 
 
执行结果:
4.6 通过POJO获取请求参数 可以在控制器方法的形参位置设置一个实体类类型的形参,此时若浏览器传输的请求参数的参数名和实体类中的属性名一致 ,那么请求参数就会为此属性赋值。
1 2 3 4 5 6 7 8 9 10 11 12 @Data @ToString @NoArgsConstructor @AllArgsConstructor public  class  User   {    private  Integer id;     private  String username;     private  String password;     private  Integer age;     private  String sex;     private  String email; } 
 
1 2 3 4 5 6 7 8 <form  th:action ="@{/testPojo}"  method ="post" >     用户名:<input  type ="text"  name ="username" > <br >      密码:<input  type ="password"  name ="password" > <br >      性别:<input  type ="radio"  name ="sex"  value ="男" > 男<input  type ="radio"  name ="sex"  value ="女" > 女<br >      年龄:<input  type ="text"  name ="age" > <br >      邮箱:<input  type ="text"  name ="email" > <br >      <input  type ="submit" >  </form > 
 
1 2 3 4 5 @RequestMapping("/testPojo") public  String testPojo (User user)   {    System.out.println(user);     return  "success" ; } 
 
执行结果:有乱码
1 User(id=null, username=admin, password=123456, age=24, sex=??·, email=123456@qq.com) 
 
4.7 解决获取请求参数的乱码问题 对于GET请求参数的乱码问题,可以在tomcat的配置文件server.xml中直接修改URLEncoding为UTF-8即可:
1 <Connector  port ="8080"  URLEncoding ="UTF-8"  ... > 
 
注:8版本以上的tomcat已默认url的编码格式为utf-8
对于post请求,解决获取请求参数的乱码问题,必须在dispacherServlet获取到请求参数之前,设置好字符集。可以使用SpringMVC提供的编码过滤器CharacterEncodingFilter,但是必须在web.xml中进行注册。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <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 > forceResponseEncoding</param-name >          <param-value > true</param-value >      </init-param >  </filter > <filter-mapping >     <filter-name > CharacterEncodingFilter</filter-name >      <url-pattern > /*</url-pattern >  </filter-mapping > 
 
注:tomcat启动时三大组件的初始化顺序:监听器 => 过滤器 => Servlet
执行结果:
5 域对象共享数据 5.1 request域共享 5.1.1 servletAPI 使用原生的servletAPI进行域对象的数据共享。