SpringMVC(三)

SpringMVC(三)

mvc:view-controller

springmvc.xml

<!--静态资源访问-->
<mvc:view-controller path="/hello" view-name="hello"/>
<mvc:annotation-driven />

当我们发送一个请求时,如果没有找到对应的mapping
则会对配置文件当中匹配mvc:view-controller

注意点:

添加后,原本自动生成的RequestMappingHandlerMapping会失效,也就不再自动生成

使用时要添加后面的内容< mvc:annotation-driven/>

如果没有添加< mvc:annotation-driven/>
则在使用@RequestMapping("testResult")的时候,会出现找不到结果页的错误

< mvc:annotation-driven />

是一种简写形式
会自动注册三个Bean

  • RequestMappingHandlerMapping
  • RequestMappingHandlerAdapter
  • ExceptionHandlerExceptionResolver

并提供了:
​ 数据绑定支持,
​ @NumberFormatannotation支持,
​ @DateTimeFormat支持,
​ @Valid支持,读写XML的支持(JAXB),
​ 读写JSON的支持(Jackson)。

form标签

简介

  • 在使用SpringMVC的时候我们可以使用Spring封装的一系列表单标签
  • 这些标签都可以访问到ModelMap中的内容

作用

  • 第一是它会自动的绑定来自Model中的一个属性值到当前form对应的实体对象
  • 第二是它支持我们在提交表单的时候使用除GET和POST之外的其他方法进行提交,包括DELETE和PUT等

使用场景

  • 当编辑时, 跳转到form表单页,传统模式要在跳转前先到数据库查询数据,然后进行表单数据回显
  • 使用form之前一定要保证有对应的bean,没有对应的bean时, 会自动以command为key到request域中查询,当找不到的时候, 会报异常

使用方式

  • 引入标签库
<%@taglib uri="http://www.springframework.org/tags/form" prefix="fm" %>
  • 创建表表单

    表单

  <a href="${pageContext.request.contextPath}/update">更新</a>

User类

  package com.itlike.domain;
  import lombok.Getter;
  import lombok.Setter;
  import org.hibernate.validator.constraints.NotBlank;
  import javax.validation.constraints.Max;
  import javax.validation.constraints.NotNull;
  import java.util.Arrays;
  
  @Setter@Getter
  public class User {
      @NotBlank(message = "姓名不能为空")
      String username;
      @Max(value = 200,message = "年龄不正确")
      Integer age;
      Integer gender;
      String[] hobby;
      Pet pet;
  
      @Override
      public String toString() {
          return "User{" +
                  "username='" + username + '\'' +
                  ", age=" + age +
                  ", gender=" + gender +
                  ", hobby=" + Arrays.toString(hobby) +
                  ", pet=" + pet +
                  '}';
      }
  }

Pet类

  package com.itlike.domain;
  import lombok.Getter;
  import lombok.Setter;
  
  @Setter@Getter
  public class Pet {
      private String name;
      private Integer id;
  
      @Override
      public String toString() {
          return "Pet{" +
                  "name='" + name + '\'' +
                  ", id='" + id + '\'' +
                  '}';
      }
  }

处理请求

@Controller
public class MyController {
    @RequestMapping("update")
    public String update(Model model) {
        ArrayList<Object> arrayList = new ArrayList<>();
        arrayList.add("篮球");
        arrayList.add("足球");
        arrayList.add("乒乓球");
        model.addAttribute("allhobby", arrayList);

        ArrayList<Object> petList = new ArrayList<>();
        Pet pet1 = new Pet();
        pet1.setId(1);
        pet1.setName("狗");

        Pet pet2 = new Pet();
        pet2.setId(2);
        pet2.setName("猫");

        Pet pet3 = new Pet();
        pet3.setId(3);
        pet3.setName("老虎");
        petList.add(pet1);
        petList.add(pet2);
        petList.add(pet3);
        model.addAttribute("petList", petList);

        User user = new User();
        user.setUsername("itlike");
        user.setAge(10);
        user.setGender(1);
        String[] hobby = new String[]{"篮球", "足球"};
        user.setPet(pet2);
        user.setHobby(hobby);

        model.addAttribute("user", user);
        return "/result.jsp";
    }
}

页面处理

<h1>结果页-------------</h1>
<fm:form modelAttribute="user"  action="${pageContext.request.contextPath}/update2">
    姓名:<fm:input path="username"/> <fm:errors path="username" cssStyle="color: red"/><br>
    年龄:<fm:input path="age"/> <fm:errors path="age" cssStyle="color: red"/><br>
    性别:<fm:radiobutton path="gender" value="0" label="男"/>
    <fm:radiobutton path="gender" value="1" label="女"/><br>
    爱好:<fm:checkboxes path="hobby" items="${allhobby}"/> <br>
    宠物:<fm:select path="pet.id" items="${petList}" itemValue="id" itemLabel="name"/> <br>
    <input type="submit" value="修改">
</fm:form>

服务器表单校验

为什么后端要做表单的校验

  • 如果只使用前端校验的话
  • 如果浏览器把JS给禁用掉,就出问题了

JSR

  • JSR 303 是 Java 为 Bean 数据合法性校验提供的标准框架,它已经包含在 JavaEE 6.0 中
  • JSR 303 通过在 Bean 属性上标注类似于 @NotNull、@Max 等标准的注解
  • 指定校验规则,并通过标准的验证接口对 Bean 进行验证

Hibernate Validator

  • 是 JSR 303 的一个参考实现,
  • 除支持所有标准的校验注解外,它还支持以下的扩展注解

常用校验规则

Bean Validation 中内置的约束
@Null           被注释的元素必须为 null       
@NotNull        被注释的元素必须不为 null       
@AssertTrue     被注释的元素必须为 true       
@AssertFalse    被注释的元素必须为 false       
@Min(value)     被注释的元素必须是一个数字,其值必须大于等于指定的最小值       
@Max(value)     被注释的元素必须是一个数字,其值必须小于等于指定的最大值       
@DecimalMin(value)  被注释的元素必须是一个数字,其值必须大于等于指定的最小值       
@DecimalMax(value)  被注释的元素必须是一个数字,其值必须小于等于指定的最大值       
@Size(max=, min=)   被注释的元素的大小必须在指定的范围内       
@Digits (integer, fraction)     被注释的元素必须是一个数字,其值必须在可接受的范围内       
@Past       被注释的元素必须是一个过去的日期       
@Future     被注释的元素必须是一个将来的日期       
@Pattern(regex=,flag=)  被注释的元素必须符合指定的正则表达式
Hibernate Validator 附加的约束
@NotBlank(message =)   验证字符串非null,且长度必须大于0       
@Email              被注释的元素必须是电子邮箱地址       
@Length(min=,max=)  被注释的字符串的大小必须在指定的范围内     
@NotEmpty           被注释的字符串的必须非空       
@Range(min=,max=,message=)  被注释的元素必须在合适的范围内 
使用Hibernate-Validator导入jar包
classmate.jar
hibernate-validator-5.jar
hibernate-validator-annotation-processor-5.jar
jboss-logging-3.1.1.jar
validation-api-1.1.0.jar
使用

​ 在配置文件当中写上

在模型当中添加对应的校验规则

User类

@Setter@Getter
public class User {
    @NotNull
    String username;
    @Max(value = 200,message = "请输入合法的年龄")
    Integer age;
    @Email(message = "请输入正确的邮箱")
    private String email;
    @Pattern(regexp="^1(3|4|5|7|8)\\d{9}$",message="请输入正确的手机号")
    private String phone;
}
在处理器方法的入参标记@valid注解即可
RequestMapping("update2")
public String update2(@Valid User user, BindingResult result,Model model) {
    int errorCount = result.getErrorCount();
    if(errorCount != 0)
    {
        //获取校验错误字段及错误信息
        List<FieldError> fieldErrors = result.getFieldErrors();
        for(FieldError fieldError:fieldErrors)
        {
            System.out.println(fieldError.getField()+":"+fieldError.getDefaultMessage());
            //这句话其实可写可不写,因为数据是会自动包装在model中的
            model.addAttribute(fieldError.getField(),fieldError.getDefaultMessage());
        }
    }
    //判断有没有错误信息
    if(result.getErrorCount() != 0){
        ArrayList<Object> arrayList = new ArrayList<>();
        arrayList.add("篮球");
        arrayList.add("足球");
        arrayList.add("乒乓球");
        model.addAttribute("allhobby", arrayList);

        ArrayList<Object> petList = new ArrayList<>();
        Pet pet1 = new Pet();
        pet1.setId(1);
        pet1.setName("狗");

        Pet pet2 = new Pet();
        pet2.setId(2);
        pet2.setName("猫");

        Pet pet3 = new Pet();
        pet3.setId(3);
        pet3.setName("老虎");
        petList.add(pet1);
        petList.add(pet2);
        petList.add(pet3);
        model.addAttribute("petList", petList);
        //回到原来界面
        return "/result.jsp";
    }
    return "/result2.jsp";
}

错误信息页面回显
使用原始表单错误信息写到Model中
<fm:form modelAttribute="user"  action="${pageContext.request.contextPath}/update2">
    姓名:<fm:input path="username"/> <fm:errors path="username" cssStyle="color: red"/><br>
    年龄:<fm:input path="age"/> <fm:errors path="age" cssStyle="color: red"/><br>
    性别:<fm:radiobutton path="gender" value="0" label="男"/>

    <fm:radiobutton path="gender" value="1" label="女"/><br>
    爱好:<fm:checkboxes path="hobby" items="${allhobby}"/> <br>
    宠物:<fm:select path="pet.id" items="${petList}" itemValue="id" itemLabel="name"/> <br>
    <input type="submit" value="修改">
</fm:form>
使用form标签
<fm:error path="username"></fm:error>

访问静态资源

概述

  • 在进行Spring MVC的配置时,通常我们会配置一个dispatcher servlet用于处理对应的URL
  • 在设置url-pattern时可以设置三种形式
/*
拦截所有   jsp  js png .css  真的全拦截.不建议使用
/
拦截所有,不包括jsp,包含.js .png.css     建议使用 
*.action 或  *.do
拦截以do action 结尾的请求

url-pattern为/时访问静态资源

方式1-< mvc:default-servlet-handler/>
方式2- 采用spring自带方法
在springmvc.xml中配置
<mvc:annotation-driven />
<mvc:resources location="/img/" mapping="/img/**"/>   
<mvc:resources location="/js/" mapping="/js/**"/>    
<mvc:resources location="/css/" mapping="/css/**"/>
描述
  • location元素表示webapp目录下的static包下的所有文件;
  • mapping元素表示以/static开头的所有请求路径,如/static/a 或者/static/a/b;
  • 该配置的作用是:DispatcherServlet不会拦截以/static开头的所有请求路径,并当作静态资源;
  • 交由Servlet处理。

Json处理

概述

  • 当前端使用Ajax发送请求时,服务器要以JSON的数据格式响应给浏览器

使用方式

​ 通过@ResponseBody来实现;注解方式

@ResponseBody

​ 1.添加json处理相关jar包

jackson-annotations-2.9.4.jar
jackson-core-2.9.4.jar
jackson-databind-2.9.4.jar

​ 2.在配置文件当中写上< mvc:annotation-driven/>
​ 3.设置映射方法的返回值为@ResponseBody

方式1-直接返回一个对象
//返回是json格式
@RequestMapping("getJson")
public @ResponseBody User getJson(){
    User user = new User();
    user.setUsername("itlike");
    user.setAge(18);
    return user;
}
方式2-返回一个List集合

@RequestMapping("formJson")
@ResponseBody
public List<User> formJson(){
    User user1 = new User();
    user1.setName("le");
    user1.setAge(14);
    
    User user2 = new User();
    user2.setName("leo");
    user2.setAge(18);
    
    ArrayList<User> arrayList = new ArrayList<>();
    arrayList.add(user1);
    arrayList.add(user2);
    return arrayList;
}
方式3-返回一个Map集合
@RequestMapping("formJson")
@ResponseBody
public Map<String,Object> formJson(){
    User user1 = new User();
    user1.setName("le");
    user1.setAge(14);
    
    User user2 = new User();
    user2.setName("leo");
    user2.setAge(18);
    
    Map<String,Object> hashMap = new HashMap<>();
    hashMap.put("user1",user1);
    hashMap.put("user2",user2);
    return hashMap;
}

表单序列化

序列化方式
<form id="myform">
    user:<input type="text" name="username"><br>
    age:<input type="text" name="age" ><br>
    爱好:<input type="checkbox" name="hobby" value="篮球"> 篮球
    <input type="checkbox" name="hobby" value="乒乓球"> 乒乓球
    <input type="checkbox" name="hobby" value="足球"> 足球
</form>
<input type="button" id="formbtn" value="发送form">

序列化转Json
(function($){
    $.fn.serializeJson=function(){
      var serializeObj={};
      var array=this.serializeArray();
      var str=this.serialize();
      $(array).each(function(){
          if(serializeObj[this.name]){
              if($.isArray(serializeObj[this.name])){
                  serializeObj[this.name].push(this.value);
              }else{
                  serializeObj[this.name]=[serializeObj[this.name],this.value];
              }
          }else{
              serializeObj[this.name]=this.value;
          }
      });
      return serializeObj;
    };
})(jQuery);

@RequestBody

作用
  • 默认情况下我们发送的都是Content-Type:application/x-www-form-urlencoded
  • 直接使用@RequestParam接收参数
  • 如果不是Content-Type:application/x-www-form-urlencoded编码的内容,例如application/json, application/xml等;
  • 使用@RequestBody接收
使用
发送Json参数
$("#submit_btn").click(function () {
    var url = "${pageContext.request.contextPath}/testAjax";
    var jsonString = {username:"le",age:10};
    $.ajax({
          type:"post",
          url:url,
          data:JSON.stringify(jsonString),
          success:function (data) {
              alert(data)
          }
    });
};
接收Json参数
@RequestMapping("testAjax")
public String testAjax(@RequestBody User user){
    System.out.println(user);
    return "success";
}
发送二进制流
<form action="${pageContext.request.contextPath}/myfile" method="post" enctype="multipart/form-data">
    <input type="file" name="myfile"> <br>
    <input type="submit" value="提交">
</form>
接收二进制流
@RequestMapping("myfile")
public String myform(@RequestBody String body){
    System.out.println(body);
    return body;
} 

视图解析器

视图解析器原理

  • 请求处理方法执行完成后,最终返回一个 ModelAndView 对象
  • 对于那些返回 String,View 或 ModelMap 等类型的处理方法
  • Spring MVC 也会在内部将它们装配成一个 ModelAndView 对象
  • 它包含了逻辑名和模型对象的视图
  • Spring MVC 借助视图解析器(ViewResolver)得到最终的视图对象(View),最终的视图可以是 JSP

视图

  • 视图的作用是渲染模型数据,将模型里的数据以某种形式呈现给客户
  • 视图对象由视图解析器负责实例化
  • 在org.springframework.web.servlet 包中定义了一个高度抽象的 View 接口

1296811-20190525110732915-1210360650.png

  • 常见实现类(InternalResourceView)
    1.将JSP或其它资源封装成一个视图
    ​ 2.是InternalResourceViewResoler默认使用的实现类

源码分析(执行DispatcherServlet)

​ 1.获取HandlerMapping映射器,包含处理器执行链
1296811-20190525110743771-150233590.png

​ 2.获取HandlerAdapter适配器

1296811-20190525110757397-1688820127.png

​ 3.调用Handler处理器,执行映射方法,返回MV(即ModelAndView,模型视图)

1296811-20190525110804203-837058591.png

1296811-20190525110811445-1346373797.png

​ 4.处理转发页面
1296811-20190525110817621-71043347.png

​ 5.在方法内部渲染页面
1296811-20190525110822275-516002279.png

​ 6.创建视图对象
1296811-20190525110827163-555690108.png

​ 7.调用View对象渲染页面
1296811-20190525110833809-1530207165.png

​ 8.在render内部解析数据

1296811-20190525110839238-1306353760.png

1296811-20190525110844158-1593260074.png

​ 9.转发到jsp页面

1296811-20190525110925819-733818134.png

文件下载

示例

//匹配.jpg .png等文件
@RequestMapping("/download/{filename:.+}")
public ResponseEntity download(@PathVariable String filename, HttpSession session) throws Exception {
    System.out.println(filename);

    //1.获取文件路径
    ServletContext servletContext = session.getServletContext();
    String realPath = servletContext.getRealPath("/download/" + filename);

    //2.把文件读取程序当中
    InputStream io = new FileInputStream(realPath);
    byte[] body = new byte[io.available()];
    io.read(body);

    //3.创建响应头
    HttpHeaders httpHeaders = new HttpHeaders();
    filename = URLEncoder.encode(filename,"UTF-8");
    httpHeaders.add("Content-Disposition","attachment;filename="+filename);//以附件形式下载

    ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(body, httpHeaders, HttpStatus.OK);

    return responseEntity;
}

文件上传

概述

  • Spring MVC 为文件上传提供了直接的支持
  • 是通过即插即用的 MultipartResolver 实现的
  • MultipartResolver是一个接口
  • Spring MVC 上下文中默认没有装配 MultipartResovler
  • 如果想使用 Spring 的文件上传功能
  • 就必须得要自己下载相关jar包
  • 自己到配置文件当中装配到springMVC当中

上传步骤

1.导入相关jar包

com.springsource.org.apache.commons.fileupload-1.2.0.jar
com.springsource.org.apache.commons.io-1.4.0.jar
com.springsource.org.apache.commons.logging-1.1.1.jar

2.在springmvc配置文件当中装配MultipartResovler

<!--上传文件配置-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="defaultEncoding" value="UTF-8"/>
    <property name="maxUploadSize" value="102400"/>
</bean>

3.实现上传代码

@RequestMapping("/upload")
public String upload(@RequestParam("file") CommonsMultipartFile file,HttpSession session) throws IOException {
    System.out.println(file.getContentType());//文件类型
    System.out.println(file.getOriginalFilename());//文件名
    System.out.println(file.getSize());
    System.out.println(file.getName());//表单项name属性

    //确定上传的路径
    ServletContext servletContext = session.getServletContext();
    String realPath = servletContext.getRealPath("/upload");
    //变成程序当中的路径
    File uploadPath = new File(realPath);
    if(!uploadPath.exists()){//如果路径不存在 ,创建一个新的
        uploadPath.mkdirs();
    }
    //确认最终的路径  /文件夹/文件名    工程的名称/upload/java.png
    String fileName = file.getOriginalFilename();
    uploadPath = new File(uploadPath+"/"+fileName);

    //开始上传
    file.transferTo(uploadPath);

    return "result.jsp";
}

多文件上传

​ WebUploader是由Baidu WebFE(FEX)团队开发的一个简单的以HTML5为主,FLASH为辅的现代文件上传组件

异常

概述

  • Spring MVC 通过 HandlerExceptionResolver 处理程序的异常,包括 Handler 映射、数据绑定以及目标方法执行时发生的异常。
  • SpringMVC 提供的 HandlerExceptionResolver 的实现类

异常处理

​ 处理 Handler 中用 @ExceptionHandler 注解定义的方法。

@RequestMapping("exception")
public String exception(){
    int i =  1 / 0;
    return "result.jsp";
}

@ExceptionHandler(value = ArithmeticException.class)
public String doexception(Exception ex){
    System.out.println("出现异常:"+ex.getMessage());
    return "/error.jsp";
}

@ExceptionHandler优先级

  • 根据继承关系
  • 找继承关系比较近的那一个
@ExceptionHandler(value = ArithmeticException.class)
public String doexception(Exception ex){
    System.out.println(ex.getMessage());
    return "error";
}

@ExceptionHandler(value = RuntimeException.class)
public String doexception2(Exception ex){
    System.out.println(ex.getMessage());
    return "error";
}

@ExceptionHandler(value = Exception.class)
public String doexception3(Exception ex){
    System.out.println(ex.getMessage());
    return "error";
}       

@ControllerAdvice

  • 如果在当前类中没有找到@ExceptionHanler

  • 则会到@ControllerAdvice 中的@ExceptionHandler 注解方法

    ExceptionController类

@ControllerAdvice
public class ExceptionController {
    @ExceptionHandler(value = Exception.class)
    public String doexception3(Exception ex){
        System.out.println(ex.getMessage());
        System.out.println("ExceptionController");
        return "error";
    }
}

国际化

概述

  • SpringMVC 根据 Accept-Language 参数判断客户端的本地化类型
  • 当接受到请求时,SpringMVC 会在上下文中查找一个本地化解析器(LocalResolver),
  • 找到后使用它获取请求所对应的本地化类型信息。

默认实现过程

要先创建国际化的资源文件

message_zh_CN.properties

language.cn=中文
language.en=英文
welcome=欢迎
name=乐乐

message_en_US.properties

language.cn=China
language.en=English
welcome=welcome
name=le     

添加配置文件
  • 注意id为messageSource
<mvc:annotation-driven />
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
    <property name="basename" value="message"/>
</bean>
添加JSTL jar包
jstl.jar
standard.jar
在页面当中编写标签
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>

<fmt:message key="welcome" /></a>
<fmt:message key="le" /></a>
<hr>
<spring:message key="welcome"/>
<spring:message key="le"/>

原理

  • 如果没有显式定义本地化解析器
  • SpringMVC 会使用 AcceptHeaderLocaleResolver:根据 HTTP 请求头的 Accept-Language 参数确定本地化类型

1296811-20190525110945821-1298415710.png

切换中英文切换

概述
  • 默认情况是通过AccepHeaderLocaleResolver来从浏览器当中获取语言信息
  • 可以从请求参数中获取本次请求对应的本地化类型。
  • 获取到本地类型后, 给写入到session当中
实现
配置文件

<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
    <property name="basename" value="message"/>
</bean>

<!--配置session本地解析器-->
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver"></bean>

<mvc:interceptors>
    <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
        <property name="paramName" value="language"/>
    </bean>
    <!--自定义 拦截器  拦截所有请求-->
   <!-- <bean class="com.le.web.interceptor.MyFirstInterceptor"></bean>-->

    <mvc:interceptor>
        <mvc:mapping path="/local"/>
        <!--除了指定的请求不拦截,其它 的都拦截-->
        <!--<mvc:exclude-mapping path=""/>-->
        <bean class="com.le.web.interceptor.MyFirstInterceptor"></bean>
    </mvc:interceptor>

    <bean class="com.le.web.interceptor.MySecInterceptor"/>
</mvc:interceptors>

属性文件

language_zh_CN.properties

language.cn=中文
language.en=英文
welcome=欢迎
name=乐乐

language_en_US.properties

language.cn=China
language.en=English
welcome=welcome
name=le     
页面信息
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>


<a href="?language=zh_CN"><spring:message code="language.cn" /></a>
<a href="?language=en_US"><spring:message code="language.en" /></a>
<hr>
<h1>
    <spring:message key="welcome"/><br>
    <spring:message key="name"/>
</h1>

拦截器

概述

  • Java 里的拦截器是动态拦截 action 调用的对象。
  • 可以在Controller中的方法执行之前与执行之后,以及页面显示完毕后, 执行指定的方法
  • 自定义的拦截器必须实现HandlerInterceptor接口

方法介绍

preHandle()
    在业务处理器处理请求之前被调用
postHandle
    在业务处理器处理完请求后
afterCompletion
    在 DispatcherServlet 完全处理完请求后被调用

SpringMVC拦截器使用

拦截所有请求
创建一个类实现HandlerInterceptor接口

MyFirstInterceptor类

package com.itlike.web.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyFirstInterceptor implements HandlerInterceptor {
    @Override
    //当处理器方法执行之前调用
    //返回值: true  放行   false  不放行    就执行不了处理器方法
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle当处理器方法执行之前调用1");
        return true;
    }

    @Override
    //当处理器方法执行之后会自动调用调用
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle当处理器方法执行之后会自动调用调用1");
    }

    @Override
    //请求处理完毕之后, 会调用
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion请求处理完毕之后,会调用1");
    }
}

MySecInterceptor类

package com.itlike.web.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MySecInterceptor implements HandlerInterceptor {
    @Override
    //当处理器方法执行之前调用
    //返回值: true  放行   false  不放行    就执行不了处理器方法
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle当处理器方法执行之前调用2");
        return false;
    }

    @Override
    //当处理器方法执行之后会自动调用调用
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle当处理器方法执行之后会自动调用调用2");
    }

    @Override
    //请求处理完毕之后, 会调用
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion请求处理完毕之后会调用2");
    }
}
配置文件当中添加拦截器
<mvc:interceptors>
    <bean class="com.itlike.web.interceptor.MyFirstInterceptor"></bean>
</mvc:interceptors>
内部源码分析

1296811-20190525111000339-775926027.png

1296811-20190525111006010-1611561963.png

拦截指定请求
<mvc:interceptors>
    <bean class="com.itlike.web.interceptor.MyFirstInterceptor"></bean>
    <mvc:interceptor>
        <!--设置拦截哪些请求-->
        <mvc:mapping path="/hello"/>
        <!--除了指定的请求不拦截,其它 的都拦截-->
        <mvc:exclude-mapping path="/hello2"/>
        <bean class="com.itlike.web.interceptor.MySecInterceptor"></bean>
    </mvc:interceptor>
</mvc:interceptors>
​ 配置多个拦截器执行顺序

1296811-20190525111043963-759139358.png

1296811-20190525111039050-1330748575.png

1296811-20190525111034788-12262468.png

1296811-20190525111030821-1521290743.png

MyFirstInterceptor类preHandle方法改成返回false

1296811-20190525111026053-924106887.png

1296811-20190525111018204-263131267.png

1296811-20190525111014377-199847719.png

拦截器完整执行分析

1296811-20190527174612656-1267552272.png

转载于:https://www.cnblogs.com/mumuyinxin/p/10921776.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值