• Spring MVC


    第一节 Spring MVC 简介

    1. Spring MVC

    SpringMVC是一个Java 开源框架, 是Spring Framework生态中的一个独立模块,它基于 Spring 实现了Web MVC(数据、业务与展现)设计模式的请求驱动类型的轻量级Web框架,为简化日常开发,提供了很大便利。

    2. Spring MVC 核心组件

    • DispatcherServlet 前置控制器

      负责接收请求、分发请求

    • Handler 处理器

      处理器包括了拦截器、控制器中的方法等,主要负责处理请求

    • HandlerMapping 处理器映射器

      解析配置文件、扫描注解,将请求与处理器进行匹配

    • HandlerAdpter 处理器适配器

      根据请求来找到匹配的处理器,这个过程称为适配

    • ViewResolver 视图解析器

      处理器执行后得到的结果可能是一个视图,但这个视图属于逻辑视图(页面中存在逻辑代码,比如循环、判断),需要使用视图解器行处理,这个过程称为渲染视图

    第二节 Spring MVC 发展演变

    
    <dependency>
        <groupId>org.springframeworkgroupId>
        <artifactId>spring-contextartifactId>
        <version>4.3.9.RELEASEversion>
    dependency>
    <dependency>
        <groupId>org.springframeworkgroupId>
        <artifactId>spring-webmvcartifactId>
        <version>4.3.9.RELEASEversion>
    dependency>
    <dependency>
        <groupId>javax.servletgroupId>
        <artifactId>javax.servlet-apiartifactId>
        <version>4.0.1version>
        <scope>providedscope>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    1. Bean的名字或ID匹配URL请求

    1.1 web.xml 配置
    <servlet>
        <servlet-name>dispatcherServletservlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
        <init-param>
            
            <param-name>contextConfigLocationparam-name>
            <param-value>classpath:spring-mvc.xmlparam-value>
        init-param>
        
        <load-on-startup>1load-on-startup>
    servlet>
    <servlet-mapping>
        <servlet-name>dispatcherServletservlet-name>
        <url-pattern>/url-pattern>
    servlet-mapping>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    1.2 spring-mvc.xml 配置
    
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        
        <property name="prefix" value="/" />
        
        <property name="suffix" value=".jsp" />
    bean>
    
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    1.3 编写控制器
    public class UserController extends AbstractController {
    
        @Override
        protected ModelAndView handleRequestInternal(HttpServletRequest req, HttpServletResponse resp) throws Exception {
            //这里使用配置的视图解析器进行解析  user => / + user + .jsp => /user.jsp
            return new ModelAndView("user");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1.4 配置控制器
    
    <bean id="/view" class="com.ch.spring.mvc.controller.UserController" />
    
    • 1
    • 2

    思考:按照这种匹配请求的方式,每一个请求需要一个控制器与之对应,这与使用Servlet开发一样,会编写大量的控制器,导致开发效率极为低下,如何解决?

    Spring 提供了方法名来匹配请求来解决这个问题
    
    • 1

    2. Bean的方法名匹配请求

    2.1 方法名解析器

    Spring 提供了控制器内的方法名的解析器 InternalPathMethodNameResolver,该解析器作用就是将方法名作为匹配URL请求的依据,与控制器关联起来

    2.2 多操作控制器

    Spring 提供了 MultiActionController 控制器类,供其他控制器类继承,在其子类中,开发者可以编写多个处理请求的方法,然后使用方法名解析器去匹配请求

    2.3 编写控制器
    public class UserMultiController extends MultiActionController {
        //这个方法就匹配 /login 请求
        //请求格式必须是 
        //ModelAndView 方法名(HttpServletRequest req, HttpServletResponse resp){}
        public ModelAndView login(HttpServletRequest req, HttpServletResponse resp){
            return new ModelAndView("login");
        }
    
        //这个方法就匹配 /register 请求
        public ModelAndView register(HttpServletRequest req, HttpServletResponse resp){
            return new ModelAndView("register");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    2.4 spring-mvc.xml 配置
     
    <bean id="methodNameResolver" class="org.springframework.web.servlet.mvc.multiaction.InternalPathMethodNameResolver" />
    
    <bean id="/login" class="com.ch.spring.mvc.controller.UserMultiController">
        <property name="methodNameResolver" ref="methodNameResolver" />
    bean>
    
    <bean id="/register" class="com.ch.spring.mvc.controller.UserMultiController">
        <property name="methodNameResolver" ref="methodNameResolver" />
    bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    思考:按照这种匹配请求的方式,如果一个控制器要处理多个请求,那么就会导致配置信息繁多的问题,后期难以维护,如何解决?

    Spring 提供了 SimpleUrlHandlerMapping 映射器, 该映射器支持一个控制器与多个请求匹配的同时也解决了配置信息繁多的问题。
    
    • 1

    3. 简单URL处理器映射

    使用SimpleUrlHandlerMapping只需要修改 spring-mvc.xml 配置即可。

    
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
        
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            
            <property name="prefix" value="/" />
            
            <property name="suffix" value=".jsp" />
        bean>
    
        
    
        
    
        
    
        
    
    
    
        
    
    
    
        <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
            <property name="mappings">
                <props>
                    <prop key="/view">userControllerprop>
                    <prop key="/user/*">userMultiControllerprop>
                props>
            property>
        bean>
        <bean id="userController" class="com.ch.spring.mvc.controller.UserController" />
        <bean id="userMultiController" class="com.ch.spring.mvc.controller.UserMultiController" />
    beans>
    
    • 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
    • 34
    • 35
    • 36
    • 37

    思考:随着项目开发的推进,开发的业务功能越来越多,控制器的数量也会伴随着增加,请求的匹配同时也会增加,同样会造成后期难以维护的问题,如何解决呢?

    Spring 提供了 DefaultAnnotationHandlerMapping 映射器,支持使用注解来匹配请求,这样就解决了请求匹配导致配置信息繁多的问题,同时还提升了开发效率。
    
    • 1

    4. 注解匹配请求

    4.1 编写控制器
    @Controller
    public class UserAnnotationController {
    
        @RequestMapping(value = "/login", method = RequestMethod.GET)
        public String login(){
            return "login";
        }
    
        @RequestMapping(value = "/register", method = RequestMethod.GET)
        public String register(){
            return "register";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    4.2 spring-mvc.xml 配置
    
    <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"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
        
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            
            <property name="prefix" value="/" />
            
            <property name="suffix" value=".jsp" />
        bean>
    
        
    
        
    
        
    
        
    
    
    
        
    
    
    
        
        
        <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
        
        <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
        
        <context:component-scan base-package="com.ch.spring.mvc.controller" />
    beans>
    
    • 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
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    5. 较新的版本配置

    
    <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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
        
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            
            <property name="prefix" value="/" />
            
            <property name="suffix" value=".jsp" />
        bean>
        
        <mvc:annotation-driven />
        
        <context:component-scan base-package="com.ch.spring.mvc.controller" />
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    第三节 Spring MVC 常用注解

    1. @Controller

    该注解是一个控制器的标识

    @Controller
    public class UserController{
        
    }
    
    • 1
    • 2
    • 3
    • 4

    2. @RequestMapping

    该注解用于匹配请求

    @Controller
    @RequestMapping("/user")
    public class UserController{
        
        @RequestMapping(value="/login", method=RequestMethod.POST)
        public int login(){
            return 1;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    3. @RequestBody

    该注解只能应用在方法的参数上,用于从请求体中获取数据并注入至参数中

    @Controller
    @RequestMapping("/user")
    public class UserController{
        
        @RequestMapping(value="/login", method=RequestMethod.POST)
        public int login(@RequestBody User user){
            return 1;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    4. @ResponseBody

    该注解用于向页面传递数据

    @Controller
    @RequestMapping("/user")
    public class UserController{
        
        @RequestMapping(value="/login", method=RequestMethod.POST)
        @ResponseBody
        public int login(@RequestBody User user){
            return 1;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    5. @RequestParam

    该注解只能应用在方法的参数上,用于从请求头中获取数据并注入至参数中

    @Controller
    @RequestMapping("/user")
    public class UserController{
        
        @RequestMapping(value="/search", method=RequestMethod.GET)
        @ResponseBody
        public List<User> searchUsers(@RequestParam(value="name") String name){
            return new ArrayList<>();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    6. @PathVariable

    该注解只能应用在方法的参数上,用于从请求路径中获取数据并注入至参数中

    @Controller
    @RequestMapping("/user")
    public class UserController{
        // /user/admin
        @RequestMapping(value="/{username}", method=RequestMethod.GET)
        @ResponseBody
        public User queryUser(@PathVariable("username") String username){
            return new User();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    7. @SessionAttributes[不重要]

    该注解只能使用在类定义上,用于从将输入放入 session 中

    @SessionAttributes(types=User.class) //会将model中所有类型为 User的属性添加到会话中。
    @SessionAttributes(value={“user1”, “user2”}) //会将model中属性名为user1和user2的属性添加到会话中。
    @SessionAttributes(types={User.class, Dept.class}) //会将model中所有类型为 User和Dept的属性添加到会话中。
    @SessionAttributes(value={“user1”,“user2”},types={Dept.class}) //会将model中属性名为user1和user2以及类型为Dept的属性添加到会话中。
    
    • 1
    • 2
    • 3
    • 4

    8. @RequestHeader

    该注解只能应用在方法的参数上,用于从请求头中获取数据

    @RequestMapping("/find")  
    public void findUsers(@RequestHeader("Content-Type") String contentType) {//从请求头中获取Content-Type的值
    }  
    
    • 1
    • 2
    • 3

    9. @CookieValue

    该注解只能应用在方法的参数上,用于从请求中获取cookie的值

    @RequestMapping("/find")  
    public void findUsers(@CookieValue("JSESSIONID") String jsessionId) {//从请cookie中获取jsessionId的值
    }  
    
    • 1
    • 2
    • 3

    10. @ControllerAdvice

    该注解只能应用在类上,表示这个类就是处理异常的控制器

    /**
     * 异常处理的控制器
     */
    @ControllerAdvice //这个注解就是spring mvc提供出来做全局异常统一处理的
    public class ExceptionController {
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    11. @ExceptionHandler

    该注解只能应用在@ControllerAdvice或者说@RestControllerAdvice标识的类的方法上,用来处理异常

    /**
     * 异常处理的控制器
     */
    @ControllerAdvice //这个注解就是spring mvc提供出来做全局异常统一处理的
    public class ExceptionController {
    
        @ExceptionHandler //异常处理器
        @ResponseBody //响应至页面
        public String handleException(Exception e){
            return e.getMessage();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    第四节 JSR-303

    1. JSR-303 简介

    JSR全称为 Java Specification Requests,表示 Java 规范提案。JSR-303是 Java 为 Java Bean 数据合法性校验提供的标准框架,它定义了一套可标注在成员变量,属性方法上的校验注解。Hibernate Validation提供了这套标准的实现。

    <dependency>
      <groupId>org.hibernategroupId>
      <artifactId>hibernate-validatorartifactId>
      <version>6.0.1.Finalversion>
      
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2. 校验注解

    注解解释注解解释
    @Null必须为null@NotNull不能为null
    @AssertTrue必须为true@AssertFalse必须为false
    @Min必须为数字,其值大于或等于指定的最小值@Max必须为数字,其值小于或等于指定的最大值
    @DecimalMin必须为数字,其值大于或等于指定的最小值@DecimalMax必须为数字,其值小于或等于指定的最大值
    @Size集合的长度@Digits必须为数字,其值必须再可接受的范围内
    @Past必须是过去的日期@Future必须是将来的日期
    @Pattern必须符合正则表达式@Email必须是邮箱格式
    @Length(min=,max=)字符串的大小必须在指定的范围内@NotEmpty不能为null,长度大于0
    @Range(min=,max=,message=)元素必须在合适的范围内@NotBlank不能为null,字符串长度大于0(限字符串)

    3. 应用

    <dependency>
        <groupId>org.springframeworkgroupId>
        <artifactId>spring-context-supportartifactId>
        <version>5.3.10version>
    dependency>
    <dependency>
        <groupId>org.springframeworkgroupId>
        <artifactId>spring-webmvcartifactId>
        <version>5.3.10version>
    dependency>
    <dependency>
        <groupId>org.hibernategroupId>
        <artifactId>hibernate-validatorartifactId>
        <version>6.0.1.Finalversion>
    dependency>
    <dependency>
        <groupId>com.alibabagroupId>
        <artifactId>fastjsonartifactId>
        <version>1.2.78version>
    dependency>
    <dependency>
        <groupId>junitgroupId>
        <artifactId>junitartifactId>
        <version>4.11version>
        <scope>testscope>
    dependency>
    
    • 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
    
    <servlet>
        <servlet-name>dispatcherServletservlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
        <init-param>
            <param-name>contextConfigLocationparam-name>
            <param-value>classpath:spring-mvc.xmlparam-value>
        init-param>
        <load-on-startup>1load-on-startup>
    servlet>
    <servlet-mapping>
        <servlet-name>dispatcherServletservlet-name>
        <url-pattern>/url-pattern>
    servlet-mapping>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/" p:suffix=".jsp" />
    
        <mvc:annotation-driven>
            <mvc:message-converters>
                
                <bean class="org.springframework.http.converter.StringHttpMessageConverter" />
                
                <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
                    <property name="supportedMediaTypes">
                        <list>
                            <value>text/html;charset=UTF-8value>
                            <value>application/json;charset=UTF-8value>
                        list>
                    property>
                bean>
            mvc:message-converters>
        mvc:annotation-driven>
    
        <context:component-scan base-package="com.ch.spring.controller" />
    beans>
    
    • 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
    import org.hibernate.validator.constraints.Length;
    import org.hibernate.validator.constraints.Range;
    
    import javax.validation.constraints.NotNull;
    
    public class User {
    
        @NotNull(message = "账号不能为空")
        @Length(min = 8, max = 15, message = "账号长度必须为8~15位")
        private String username;
    
        @NotNull(message = "密码不能为空")
        @Length(min = 8, max = 20, message = "密码长度必须为8~20位")
        private String password;
    
        @Range(min = 0, max = 120, message = "年龄只能在0~120岁之间")
        private int age;
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    }
    
    
    import org.springframework.stereotype.Controller;
    import org.springframework.validation.BindingResult;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import javax.validation.Valid;
    
    @Controller
    @RequestMapping("/user")
    public class UserController {
    
        @RequestMapping("/add")
        @ResponseBody
        public Object saveUser(@Valid User user, BindingResult result){
            if(result.hasErrors()) return result.getAllErrors();
            return 1;
        }
    }
    
    • 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
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    第五节 RESTFUL

    1. RESTFUL 简介

    REST全称为 Representational State Transfer,表示 表述性状态转移

    RESTFUL有如下特点:

    • 每一个 URI 代表一种资源
    • 客户端使用GET、POST、PUT、DELETE4 个表示操作方式的动词对服务端资源进行操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源

    2. RESTFUL 请求

    /user GET => 获取用户资源
    /user POST => 增加用户资源
    /user PUT => 修改用户资源
    /user DELETE => 删除用户资源
    
    /user/{username} GET => 获取指定用户资源  这是RESTFUL风格中子资源的表述方式
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3. Spring 对 RESTFUL 的支持

    3.1 @RestController

    该注解只能应用于类上,相当于@Controller 和 @ResponseBody 注解的组合。表示该类中的所有方法执行完成后所返回的结果直接向页面输出

    3.2 @GetMapping
    3.2 @PostMapping
    3.2 @PutMapping
    3.2 @DeleteMapping

    第六节 静态资源处理

    1. 静态资源无法访问的原因

    静态资源包含html、js、css、图片、字体文件等。静态文件没有url-pattern,所以默认是访问不到的。之所以可以访问,是因为tomcat中有一个全局的servlet:org.apache.catalina.servlets.DefaultServlet,它的url-pattern是 “/”, 所以项目中不能匹配的静态资源请求,都由这个Servlet来处理。但在SpringMVC中DispatcherServlet也采用了"/" 作为url-pattern, 那么项目中不会再使用全局的Serlvet,这样就造成了静态资源不能完成访问。

    2. 处理方案

    2.1 方案一

    DispathcerServlet 对应的 url-pattern 修改为 “/” 以外的其他匹配样式即可。比如 *.do, *.action。这样修改后,发送请求时,请求URL必须匹配 .do 或者 .action。

    2.2 方案二
    
    <servlet-mapping>
        <servlet-name>defaultservlet-name>
        <url-pattern>/static/*url-pattern>
      servlet-mapping>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    2.2 方案三
    
    
    <mvc:default-servlet-handler/>
    
    <mvc:resources mapping="/static/**" location="/static/" />
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    第七节 中文乱码处理

    
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                          http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
             version="4.0">
      <display-name>Archetype Created Web Applicationdisplay-name>
      <servlet>
        <servlet-name>dispatcherServletservlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
        <init-param>
          <param-name>contextConfigLocationparam-name>
          <param-value>classpath:spring-mvc.xmlparam-value>
        init-param>
        <load-on-startup>1load-on-startup>
      servlet>
      <servlet-mapping>
        <servlet-name>dispatcherServletservlet-name>
        <url-pattern>/url-pattern>
      servlet-mapping>
    
      <filter>
        <filter-name>encodingFilterfilter-name>
        
        <filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
        <init-param>
          
          <param-name>encodingparam-name>
          <param-value>UTF-8param-value>
        init-param>
        <init-param>
          
          <param-name>forceEncodingparam-name>
          <param-value>trueparam-value>
        init-param>
      filter>
      <filter-mapping>
        <filter-name>encodingFilterfilter-name>
        <url-pattern>/*url-pattern>
      filter-mapping>
    web-app>
    
    • 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
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    第八节 Spring MVC工作原理

    在这里插入图片描述

    checkMultipart(request); //检测是否是多部分请求,这个只可能在文件上传的时候为真
    
    
    getHandler(processedRequest); //获取处理器 => 遍历HandlerMapping,找到匹配当前请求的执行器链
    //没有找到执行器链 就直接向页面报一个404
    noHandlerFound(processedRequest, response);
    //找到处理当前请求的适配器
    HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
    
    //控制器之前执行的拦截器将先执行,如果拦截器不通过,则方法直接结束
    if (!mappedHandler.applyPreHandle(processedRequest, response)) {
        return;
    }
    //控制器处理请求,可能会得到一个ModelAndView
    mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
    
    //控制器之后的拦截器执行
    mappedHandler.applyPostHandle(processedRequest, response, mv);
    //处理分发的结果:这个结果就是控制器处理后的结果
    processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
    //拦截器在控制器给出的结果DispatcherServlet处理后执行
    triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
  • 相关阅读:
    7.19模拟赛总结
    Java基础-多态性应用
    横向的Excel输出为pdf自动分成两页怎么办?不分页,铺满整张纸的方法来了
    netcore Polly.Core
    18 - 如何设置线程池大小?
    CSDN 技能树使用体验与产品分析(1)
    uniapp常见兼容性问题
    AI搞钱——工具篇之视频、音频转文字
    期刊会议排名、信息检索网站推荐以及IEEE Latex模板下载
    Java面向对象
  • 原文地址:https://blog.csdn.net/GSztx/article/details/132624193