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 />

<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

使用

​ 在配置文件当中写上mvc:annotation-driven/

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

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自带mvc:resources方法

在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 接口

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

源码分析(执行DispatcherServlet)

​ 1.获取HandlerMapping映射器,包含处理器执行链

​ 2.获取HandlerAdapter适配器

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

​ 4.处理转发页面

​ 5.在方法内部渲染页面

​ 6.创建视图对象

​ 7.调用View对象渲染页面

​ 8.在render内部解析数据

​ 9.转发到jsp页面

文件下载

示例

//匹配.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 参数确定本地化类型

切换中英文切换

概述

  • 默认情况是通过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>
内部源码分析

拦截指定请求

<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>

​ 配置多个拦截器执行顺序

MyFirstInterceptor类preHandle方法改成返回false

拦截器完整执行分析

posted @ 2019-05-25 11:11  海韵༒听心  阅读(256)  评论(0编辑  收藏  举报