• JSR303和拦截器


    目录

    一、JSR303

    1.简介

    2.JSR303服务端校验步骤 

    二、拦截器的初步认识 

     1.什么是拦截器

     2.拦截器于过滤器

    2.1 什么是过滤器(Filter) 

    2.2 拦截器于过滤器的区别 

    3.应用场景 

    4.拦截器快速入门 

     4.1 入门案例

    4.2 拦截器方法说明 

     4.3拦截器使用步骤

    三、拦截器链 

    1.多拦截器 

    四、登录权限控制 

    五、总结 

    1.JSR303 

    2.拦截器


    一、JSR303

    1.简介

    服务端验证

    2.JSR303服务端校验步骤 

    2.1 pom依赖导入
    2.2 在待校验的数据库列段对应的实体类打上校验标签
        非空效验
    2.3 在controller层
        方法上添加@valid注解配合前面的校验标签
        添加bindingResult,此对象包含了所有  效验未通过的错误信息

    2.4 可以将所有的错误信息以map集合的方式保存,并且传递到前台页面展示

     2.1  pom 依赖

    1. <dependency>
    2. <groupId>org.hibernate</groupId>
    3. <artifactId>hibernate-validator</artifactId>
    4. <version>6.0.7.Final</version>
    5. </dependency>

    2.2 Clazz.java实体类

    1. package com.zking.ssm.model;
    2. import javax.validation.constraints.NotBlank;
    3. import javax.validation.constraints.NotEmpty;
    4. import javax.validation.constraints.NotNull;
    5. /**
    6. * @NotNull :作用于基本数据类型
    7. * @NotEmpty: 作用于集合
    8. * @NotBlank: 作用于字符串
    9. */
    10. public class Clazz {
    11. @NotNull
    12. protected Integer cid;
    13. @NotBlank
    14. protected String cname;
    15. @NotEmpty
    16. protected String cteacher;
    17. protected String pic;
    18. public Clazz(Integer cid, String cname, String cteacher, String pic) {
    19. this.cid = cid;
    20. this.cname = cname;
    21. this.cteacher = cteacher;
    22. this.pic = pic;
    23. }
    24. public Clazz() {
    25. super();
    26. }
    27. public Integer getCid() {
    28. return cid;
    29. }
    30. public void setCid(Integer cid) {
    31. this.cid = cid;
    32. }
    33. public String getCname() {
    34. return cname;
    35. }
    36. public void setCname(String cname) {
    37. this.cname = cname;
    38. }
    39. public String getCteacher() {
    40. return cteacher;
    41. }
    42. public void setCteacher(String cteacher) {
    43. this.cteacher = cteacher;
    44. }
    45. public String getPic() {
    46. return pic;
    47. }
    48. public void setPic(String pic) {
    49. this.pic = pic;
    50. }
    51. }

    运行结果如图所示:

    我们直接提交,然后它也还是会直接运行到后台,也就是说我们还没有做然后的校验,它最后运行结果会报错如图所示:

     我们希望最终效果是我们没有填它会在后面提示我们,cid不能为空以及cname不能为空等等,这样的效果演示,上面的实体类是因为我们导入了注解依赖,才会有这些注解,怎么才能让注解生效?看下面

    Clazz.java 实体类

    1. package com.zking.ssm.model;
    2. import javax.validation.constraints.NotBlank;
    3. import javax.validation.constraints.NotEmpty;
    4. import javax.validation.constraints.NotNull;
    5. /**
    6. * @NotNull :作用于基本数据类型
    7. * @NotEmpty: 作用于集合
    8. * @NotBlank: 作用于字符串
    9. */
    10. public class Clazz {
    11. @NotNull(message = "cid不能为空")
    12. protected Integer cid;
    13. @NotBlank(message = "班级名称不能为空")
    14. protected String cname;
    15. @NotEmpty(message = "教员老师不能为空")
    16. protected String cteacher;
    17. protected String pic;
    18. public Clazz(Integer cid, String cname, String cteacher, String pic) {
    19. this.cid = cid;
    20. this.cname = cname;
    21. this.cteacher = cteacher;
    22. this.pic = pic;
    23. }
    24. public Clazz() {
    25. super();
    26. }
    27. public Integer getCid() {
    28. return cid;
    29. }
    30. public void setCid(Integer cid) {
    31. this.cid = cid;
    32. }
    33. public String getCname() {
    34. return cname;
    35. }
    36. public void setCname(String cname) {
    37. this.cname = cname;
    38. }
    39. public String getCteacher() {
    40. return cteacher;
    41. }
    42. public void setCteacher(String cteacher) {
    43. this.cteacher = cteacher;
    44. }
    45. public String getPic() {
    46. return pic;
    47. }
    48. public void setPic(String pic) {
    49. this.pic = pic;
    50. }
    51. }

    2.3 控制层 ClazzController.java

    1. package com.zking.ssm.controller;
    2. import com.zking.ssm.biz.ClazzBiz;
    3. import com.zking.ssm.model.Clazz;
    4. import com.zking.ssm.model.dto.ClazzDto;
    5. import com.zking.ssm.util.PageBean;
    6. import org.apache.commons.io.FileUtils;
    7. import org.springframework.beans.factory.annotation.Autowired;
    8. import org.springframework.http.HttpHeaders;
    9. import org.springframework.http.HttpStatus;
    10. import org.springframework.http.MediaType;
    11. import org.springframework.http.ResponseEntity;
    12. import org.springframework.stereotype.Controller;
    13. import org.springframework.validation.BindingResult;
    14. import org.springframework.validation.FieldError;
    15. import org.springframework.validation.ObjectError;
    16. import org.springframework.web.bind.annotation.RequestMapping;
    17. import org.springframework.web.multipart.MultipartFile;
    18. import javax.servlet.http.HttpServletRequest;
    19. import javax.validation.Valid;
    20. import java.io.File;
    21. import java.io.FileOutputStream;
    22. import java.io.InputStream;
    23. import java.util.HashMap;
    24. import java.util.List;
    25. import java.util.Map;
    26. /**
    27. * @author 敢敢
    28. * @site www.javajwj.com
    29. * @company xxx公司
    30. * @create  2022-08-18 21:50
    31. */
    32. @Controller
    33. //加上我们的窄化入境,在做项目一定要加
    34. @RequestMapping("/clz")
    35. public class ClazzController {
    36. @Autowired
    37. private ClazzBiz clazzBiz;
    38. // list————>bookList
    39. // toList————>重定向list————>"redirect:clz/list"
    40. // toEdit————>跳转到编辑界面————>clzEdit
    41. // Clazz:以前是通过模型驱动接口封装,现在是直接在方法中接收参数即可
    42. @RequestMapping("/list")
    43. public String list(Clazz clazz, HttpServletRequest request){
    44. PageBean pageBean = new PageBean();
    45. pageBean.setRequest(request);
    46. List<Clazz> lst = this.clazzBiz.listPager(clazz, pageBean);
    47. request.setAttribute("lst",lst);
    48. request.setAttribute("pageBean",pageBean);
    49. return "clzList";
    50. }
    51. @RequestMapping("/toEdit")
    52. public String toEdit(Clazz clazz, HttpServletRequest request){
    53. Integer cid = clazz.getCid();
    54. // 传递的id代表了修改,没传代表了新增
    55. if(cid != null){
    56. List<Clazz> lst = this.clazzBiz.listPager(clazz, null);
    57. request.setAttribute("b",lst.get(0));
    58. }
    59. return "clzEdit";
    60. }
    61. /**
    62. * @Valid:是与实体类中 的服务端校验 注解配合使用的
    63. * BindingResult:存放了所以违背 效验的错误信息
    64. * @param clazz
    65. * @param bindingResult
    66. * @return
    67. */
    68. // 给数据添加服务端校验
    69. @RequestMapping("/valiAdd")
    70. public String valiAdd(@Valid Clazz clazz, BindingResult bindingResult,HttpServletRequest request){
    71. // 如果服务端验证不通过,有错误
    72. if(bindingResult.hasErrors()){//违背了规则
    73. Map msg = new HashMap<>();
    74. // 服务端验证了实体类的多个属性,多个属性都没有验证通过
    75. List<FieldError> fieldErrors = bindingResult.getFieldErrors();
    76. for (FieldError fieldError : fieldErrors) {
    77. // 将多个属性的验证失败信息输送到控制台 比如:cid 提示cid不能为空
    78. System.out.println(fieldError.getField() + ":" + fieldError.getDefaultMessage());
    79. // msg.put(cid,cid不能为空)
    80. msg.put(fieldError.getField(),fieldError.getDefaultMessage());
    81. }
    82. request.setAttribute("msg",msg);
    83. // 如果出现了错误,应该讲提示语显示在 表单提交元素后方
    84. return "clzList";
    85. }
    86. else {//没有违背规则
    87. this.clazzBiz.insertSelective(clazz);
    88. }
    89. return "redirect:/clz/list";
    90. }
    91. @RequestMapping("/add")
    92. public String add(Clazz clazz){
    93. this.clazzBiz.insertSelective(clazz);
    94. return "redirect:/clz/list";
    95. }
    96. @RequestMapping("/edit")
    97. public String edit(Clazz clazz){
    98. this.clazzBiz.updateByPrimaryKeySelective(clazz);
    99. return "redirect:/clz/list";
    100. }
    101. @RequestMapping("/del")
    102. public String del(Clazz clazz){
    103. this.clazzBiz.deleteByPrimaryKey(clazz.getCid());
    104. return "redirect:/clz/list";
    105. }
    106. // 文件上传
    107. @RequestMapping("/upload")
    108. public String upload(ClazzDto clazzDto){
    109. try {
    110. // 前台上传文件
    111. MultipartFile picFile = clazzDto.getPicFile();
    112. // 实际应该配置到 resource.properties 中
    113. String diskPath = "E:/temp/images/";// 图片的存放地址
    114. // 最终访问:http:localhost:8080/upload/mvc/22.jsp
    115. String requestPath = "/upload/mvc/";// 数据库保存的地址,也是访问地址
    116. // 拿到上传文件的名字
    117. String fileName = picFile.getOriginalFilename();// 22.jsp
    118. // 完成文件上传
    119. FileUtils.copyInputStreamToFile(picFile.getInputStream(),new File(diskPath+fileName));
    120. // 将图片上传之后,并且保存到数据库中
    121. Clazz clazz = new Clazz();
    122. clazz.setCid(clazzDto.getCid());
    123. clazz.setPic(requestPath+fileName);
    124. this.clazzBiz.updateByPrimaryKeySelective(clazz);
    125. }catch (Exception e){
    126. e.printStackTrace();
    127. }
    128. return "redirect:/clz/list";
    129. }
    130. // 文件下载
    131. @RequestMapping("/download")
    132. public ResponseEntity download(ClazzDto clazzDto){
    133. try {
    134. // 1.点击下载传递文件的ID,通过文件的ID查询文件的路径
    135. Clazz clazz = this.clazzBiz.selectByPrimaryKey(clazzDto.getCid());
    136. String pic = clazz.getPic();// 数据库中的图片路径 比如:/upload/mvc/33.jpg
    137. // 实际应该配置到 resource.properties 中
    138. String diskPath = "E:/temp/images/";// 图片的存放地址
    139. // 最终访问:http:localhost:8080/upload/mvc/22.jsp
    140. String requestPath = "/upload/mvc/";// 数据库保存的地址,也是访问地址
    141. //        2.通过文件的请求地址,转换成文件存放的硬盘地址
    142. String realPath = pic.replace(requestPath,diskPath);// E:/temp/images/2.png
    143. // 有可能图片是中文的所以要转乱码
    144. String fileName = realPath.substring(realPath.lastIndexOf("/")+1);
    145. //        3.将硬盘中文件下载下来---->固定代码
    146. //下载关键代码
    147. File file=new File(realPath);
    148. HttpHeaders headers = new HttpHeaders();//http头信息
    149. String downloadFileName = new String(fileName.getBytes("UTF-8"),"iso-8859-1");//设置编码
    150. headers.setContentDispositionFormData("attachment", downloadFileName);
    151. headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
    152. //MediaType:互联网媒介类型 contentType:具体请求中的媒体类型信息
    153. return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),headers, HttpStatus.OK);
    154. }catch (Exception e){
    155. e.printStackTrace();
    156. }
    157. // 下载好了就不需要重新查询一遍了
    158. return null;
    159. }
    160. }

     2.4 前端        clzEdit.jsp

    1. <%@ page language="java" contentType="text/html; charset=UTF-8"
    2. pageEncoding="UTF-8"%>
    3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    4. <html>
    5. <head>
    6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    7. <title>博客的编辑界面</title>
    8. </head>
    9. <body>
    10. <%--<form action="${pageContext.request.contextPath }/clz/${empty b ? 'add' : 'edit'}" method="post">--%>
    11. <form action="${pageContext.request.contextPath }/clz/${empty b ? 'valiAdd' : 'edit'}" method="post">
    12. cid:<input type="text" name="cid" value="${b.cid }"><span style="color: red">${msg.cid}</span><br>
    13. cname:<input type="text" name="cname" value="${b.cname }"><span style="color: red">${msg.cname}</span><br>
    14. cteacher:<input type="text" name="cteacher" value="${b.cteacher }"><span style="color: red">${msg.cteacher}</span><br>
    15. <input type="submit">
    16. </form>
    17. </body>
    18. </html>

    运行一下看看有没有生效我们的原来的add就换成了valiAdd如图所示:

     我们加了一个班级然后它就提示两个为空,我们加两个也一样的增加不成功,要全部加上

       

    我们增加个15 如图所示: 

    二、拦截器的初步认识 

     1.什么是拦截器

     SpringMVC的处理器拦截器,类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。------>拦截器就类似于我们的过滤器

      依赖于web框架,在实现上基于Java的反射机制,属于面向切面编程(AOP)的一种运用。由于拦截器是基于web框架的调用,因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个 
      controller生命周期之内可以多次调用。

     2.拦截器于过滤器

    2.1 什么是过滤器(Filter) 

      依赖于servlet容器。在实现上基于函数回调,可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次。使用过滤器的目的是用来做一些过滤操作,比如:在过滤器中修改字符编码; 在过滤器中修改HttpServletRequest的一些参数,包括:过滤低俗文字、危险字符等。

    2.2 拦截器于过滤器的区别 

    过滤器(Filter): 

        1) filter属于Servlet技术,只要是web工程都可以使用
        2) filter主要对所有请求过滤
        3) filter的执行时机早于Interceptor

    拦截器(interceptor) 

        1) interceptor属于SpringMVC技术,必须要有SpringMVC环境才可以使用。

                                                                                            ————》也就是Springmvc的jar包
        2) interceptor通常对处理器Controller进行拦截
        3) interceptor只能拦截dispatcherServlet处理的请求

    3.应用场景 

     1)日志记录:记录请求信息的日志,以便进行信息监控、信息统计、计算PV(Page View)等。

     2)权限检查:如登录检测,进入处理器检测是否登录,如果没有直接返回到登录页面;

     3)性能监控:有时候系统在某段时间莫名其妙的慢,可以通过拦截器在进入处理器之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间(如果有反向代理,如apache可以自动记录);

     4)通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Locale、Theme信息等,只要是多个Controller中的处理方法都需要的,我们就可以使用拦截器实现。

                    ——————》也就是只要属于面向切面编程(AOP)拦截器就可以做

    4.拦截器快速入门 

     4.1 入门案例

        创建HelloController
        创建自定义拦截器并实现HandlerInterceptor接口。

       
           
       

    4.2 拦截器方法说明 

    preHandle方法

    作用:用于对拦截到的请求进行预处理,方法接收布尔(true,false)类型的返回值,返回true:放行,false:不放行。

    执行时机:在处理器方法执行前执行

    方法参数:

            ① request 请求对象

            ② response 响应对象

            ③ handler 拦截到的方法处理

    postHandle 方法

    作用:用于对拦截到的请求进行后处理,可以在方法中对模型数据和视图进行修改

    执行时机:在处理器的方法执行后,视图渲染之前

    方法参数:

            ① request 请求对象

            ② response 响应对象

            ③ handler 拦截到的处理器方法

            ④ ModelAndView 处理器方法返回的模型和视图对象,可以在方法中修改模型和视图

    afterCompletion方法

    作用:用于在整个流程完成之后进行最后的处理,如果请求流程中有异常,可以在方法中获取对象

    执行时机:视图渲染完成后(整个流程结束之后)

    方法参数:

            ① request 请求参数

            ② response 响应对象

            ③ handler 拦截到的处理器方法

            ④ ex 异常对象

     4.3拦截器使用步骤

        4.1 实现HandlerInterceptor接口   对应实现三个方法    预处理——>处理后——>完成后
        4.2 完成springmvc-mybatis.xml中的配置 

    代码演示:

    创建包,创建类实现HandlerInterceptor接口

      

    OneHandlerInterceptor.java

    1. package com.zking.ssm.interceptor;
    2. import org.springframework.web.servlet.HandlerInterceptor;
    3. import org.springframework.web.servlet.ModelAndView;
    4. import javax.servlet.http.HttpServletRequest;
    5. import javax.servlet.http.HttpServletResponse;
    6. /**
    7. * @author 敢敢
    8. * @site www.javajwj.com
    9. * @company xxx公司
    10. * @create  2022-08-20 11:02
    11. */
    12. public class OneHandlerInterceptor implements HandlerInterceptor {
    13. @Override
    14. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    15. // 预处理
    16. System.out.println("[OneHandlerInterceptor] . preHandle");
    17. return true;
    18. }
    19. @Override
    20. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    21. // 后处理
    22. System.out.println("[OneHandlerInterceptor] . postHandle...");
    23. }
    24. @Override
    25. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    26. // 完成后执行
    27. System.out.println("[OneHandlerInterceptor] . afterCompletion");
    28. }
    29. }

     配置拦截器        springmvc-servlet.xml

    1. "1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xmlns:context="http://www.springframework.org/schema/context"
    5. xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop"
    6. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    7. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
    8. <aop:aspectj-autoproxy/>
    9. <context:component-scan base-package="com.zking.ssm"/>
    10. <mvc:annotation-driven>mvc:annotation-driven>
    11. <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    12. <property name="viewClass"
    13. value="org.springframework.web.servlet.view.JstlView">property>
    14. <property name="prefix" value="/"/>
    15. <property name="suffix" value=".jsp"/>
    16. bean>
    17. <mvc:resources location="/static/" mapping="/static/**"/>
    18. <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    19. <property name="defaultEncoding" value="UTF-8">property>
    20. <property name="maxUploadSize" value="52428800">property>
    21. <property name="resolveLazily" value="true"/>
    22. bean>
    23. <mvc:interceptors>
    24. <bean class="com.zking.ssm.interceptor.OneHandlerInterceptor">bean>
    25. mvc:interceptors>
    26. beans>

    HelloController.java

    1. package com.zking.ssm.interceptor;
    2. import org.springframework.stereotype.Controller;
    3. import org.springframework.web.bind.annotation.RequestMapping;
    4. /**
    5. * @author 敢敢
    6. * @site www.javajwj.com
    7. * @company xxx公司
    8. * @create  2022-08-20 11:14
    9. */
    10. @Controller
    11. public class HelloController {
    12. @RequestMapping("hello")
    13. public String hello(){
    14. System.out.println("进入业务方法...");
    15. return "index";
    16. }
    17. }

    我们看看它们的执行顺序————运行结果如图所示: 

     

    在来运行结果如图所示:它就不会执行我们的业务方法

    而且我们的     Hello World!    也没有了

     

    三、拦截器链 

    1.多拦截器 

    拦截器链的概率:如果多个拦截器能够对相同的请求进行拦截,则多个拦截器会形成一个拦截器链,主要理解拦截器中各个拦截器的执行顺序。拦截器链中多个拦截器的执行顺序,根拦截器的配置顺序有关,先配置的先执行。

    1. <mvc:interceptors>
    2. <mvc:interceptor>
    3. <mvc:mapping path="/**"/>
    4. <bean class="com.zking.springmvc07.interceptor.CustomInterceptor"/>
    5. </mvc:interceptor>
    6. <mvc:interceptor>
    7. <mvc:mapping path="/user/**"/>
    8. <bean class="com.zking.springmvc07.interceptor.Custom2Interceptor"/>
    9. </mvc:interceptor>
    10. </mvc:interceptors>

    我们在去写一个类

    TwoHandlerInterceptor.java

    1. package com.zking.ssm.interceptor;
    2. import org.springframework.web.servlet.HandlerInterceptor;
    3. import org.springframework.web.servlet.ModelAndView;
    4. import javax.servlet.http.HttpServletRequest;
    5. import javax.servlet.http.HttpServletResponse;
    6. /**
    7. * @author 敢敢
    8. * @site www.javajwj.com
    9. * @company xxx公司
    10. * @create  2022-08-20 11:02
    11. */
    12. public class TwoHandlerInterceptor implements HandlerInterceptor {
    13. @Override
    14. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    15. // 预处理
    16. System.out.println("[TwoHandlerInterceptor] . preHandle");
    17. return true;
    18. }
    19. @Override
    20. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    21. // 后处理
    22. System.out.println("[TwoHandlerInterceptor] . postHandle...");
    23. }
    24. @Override
    25. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    26. // 完成后执行
    27. System.out.println("[TwoHandlerInterceptor] . afterCompletion");
    28. }
    29. }

    配置文件 springmvc-servlet.xml

    1. <!--配置拦截器-->
    2. <!-- <mvc:interceptors>
    3. &lt;!&ndash;针对与所有的请求进行拦截&ndash;&gt;
    4. <bean class="com.zking.ssm.interceptor.OneHandlerInterceptor"></bean>
    5. </mvc:interceptors>-->
    6. <!--
    7. 配置拦截器链
    8. /**:是拦截所有请求
    9. /clz/**:是拦截以clz开头的
    10. -->
    11. <mvc:interceptors>
    12. <mvc:interceptor>
    13. <mvc:mapping path="/**"/>
    14. <bean class="com.zking.ssm.interceptor.OneHandlerInterceptor"></bean>
    15. </mvc:interceptor>
    16. <mvc:interceptor>
    17. <mvc:mapping path="/clz/**"/>
    18. <bean class="com.zking.ssm.interceptor.TwoHandlerInterceptor"></bean>
    19. </mvc:interceptor>
    20. </mvc:interceptors>

    我们预测运行结果的是怎样的:

       http://localhost:8080/hello   one prehandle/posthandle/aftercomplation
        http://localhost:8080/clz/list    one two
        one ——prehandle
        two ——prehandle
        业务方法
        two ——posthandle
        one ——posthandle
        two——aftercomplation
        one ——aftercomplation

    运行结果如图所示:

     

     

    第二测试结果如图所示:

    在接着看下面如图所示:

    就比如这样一张图:

    就比如这样理解:你一开始进去的时候从one的prehandle进行——》two prehandle

            出来的时候从 two的posthandle出来——》one posthandle

            结束也是如此 two aftercomplation——》one aftercomplation

    四、登录权限控制 

    目前是可以直接访问数据的    http://localhost:8080/clz/list ,现在需要登录后才能访问

     springmvc-servlet.xml        我们肯定是拦截所有的

    1. <!--
    2. 配置拦截器链
    3. /**:是拦截所有请求
    4. /clz/**:是拦截以clz开头的
    5. -->
    6. <mvc:interceptors>
    7. <mvc:interceptor>
    8. <mvc:mapping path="/**"/>
    9. <bean class="com.zking.ssm.interceptor.OneHandlerInterceptor"></bean>
    10. </mvc:interceptor>
    11. <!--<mvc:interceptor>
    12. <mvc:mapping path="/clz/**"/>
    13. <bean class="com.zking.ssm.interceptor.TwoHandlerInterceptor"></bean>
    14. </mvc:interceptor>-->
    15. </mvc:interceptors>

    拦截器 OneHandlerInterceptor.java

    1. package com.zking.ssm.interceptor;
    2. import org.springframework.web.servlet.HandlerInterceptor;
    3. import org.springframework.web.servlet.ModelAndView;
    4. import javax.servlet.http.HttpServletRequest;
    5. import javax.servlet.http.HttpServletResponse;
    6. /**
    7. * @author 敢敢
    8. * @site www.javajwj.com
    9. * @company xxx公司
    10. * @create  2022-08-20 11:02
    11. */
    12. public class OneHandlerInterceptor implements HandlerInterceptor {
    13. @Override
    14. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    15. // 预处理
    16. System.out.println("[OneHandlerInterceptor] . preHandle");
    17. // 如果是 login/logout 这个请求,就直接放行
    18. // 拿到路径请求地址
    19. String url = request.getRequestURL().toString();
    20. if(url.indexOf("/login") > 0 || url.indexOf("/logout") > 0){
    21. //如果是 登录、退出 中的一种
    22. return true;
    23. }
    24. // 代表不是登录,也不是退出
    25. // 对于请求业务方法,除了登录、退出,其他操作都需要判断是否 session 登录成功过 ,才能访问
    26. String uname = (String) request.getSession().getAttribute("uname");
    27. if(uname == null || "".equals(uname)){
    28. response.sendRedirect("/login.jsp");
    29. return false;
    30. }
    31. return false;
    32. }
    33. @Override
    34. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    35. // 后处理
    36. System.out.println("[OneHandlerInterceptor] . postHandle...");
    37. }
    38. @Override
    39. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    40. // 完成后执行
    41. System.out.println("[OneHandlerInterceptor] . afterCompletion");
    42. }
    43. }

     业务代码 LoginController.java

    1. package com.zking.ssm.controller;
    2. import org.springframework.stereotype.Controller;
    3. import org.springframework.web.bind.annotation.RequestMapping;
    4. import javax.servlet.http.HttpServletRequest;
    5. /**
    6. * @author 敢敢
    7. * @site www.javajwj.com
    8. * @company xxx公司
    9. * @create  2022-08-20 12:12
    10. */
    11. @Controller
    12. public class LoginController {
    13. @RequestMapping("/login")
    14. public String login(HttpServletRequest request){
    15. // 登录成功一般需要 保存 用户信息
    16. String uname = request.getParameter("uname");
    17. if("zhangsan".equals(uname)){
    18. request.getSession().setAttribute("uname",uname);
    19. }
    20. return "index";
    21. }
    22. @RequestMapping("/logout")
    23. public String logout(HttpServletRequest request){
    24. // 做销毁
    25. request.getSession().invalidate();
    26. return "index";
    27. }
    28. }

    页面代码        login.jsp

    1. <%--
    2. Created by IntelliJ IDEA.
    3. User: zjjt
    4. Date: 2022/8/20
    5. Time: 12:16
    6. To change this template use File | Settings | File Templates.
    7. --%>
    8. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    9. <html>
    10. <head>
    11. <title>Title</title>
    12. </head>
    13. <body>
    14. 登录界面
    15. </body>
    16. </html>

    运行结果如图所示: 这里是不是就直接让它进入登录界面

     接着我们去登录一下如图所示:

    那么我们在去访问一下  http://localhost:8080/clz/list   就不能访问了

    我们输入http:localhost:8080/clz/list 它还是会让你返回登录界面的 

    为什么呢?因为我们指定了登录人,我们这里就没有连接数据库了,所以我们只能登录zhangsan这样才可以进入如图所示: 

     

    我们在去执行 http://localhost:8080/clz/list   就可以访问了

     

    我们在去执行logout  ,退出

    我们在去查询list就不能进行了如图所示: 

     

    五、总结 

    1.JSR303 

    ① 作用:做服务端的效验

    ② 导入pom依赖 hibernate-validate

            实体类属性添加效验的注解 @notNull        @notBlank

            controller 层方法上  添加@valid 效验实体类

            bindingResult  包含了所有的错误信息

    2.拦截器 

    ① 简介:AOP的一种体现形式,类似于过滤器

    ② 与过滤器的区别? 

            拦截器多次调用,过滤器只有一次

            拦截器依赖于SpringMVC,过滤器是依赖于web容器

            拦截器只能拦截DispatcherServlet处理的请求,而过滤器可以处理所有的请求

    ③ 使用

            实现HandlerInterceptor接口

            SpringMVC.xml中进行配置

            怎么配置?

                   

                           

                   

                   

                           

                           

                   

  • 相关阅读:
    完美解决:sh: /usr/bin/xauth: not found
    企业财务管理有什么作用?怎么突破企业财务管理新变局?
    【云原生--Kubernetes】Pod重启策略
    webpack 面试题
    详解SPI
    【单链表基本操作的实现】
    Python 路径管理
    vue3-基础知识(4)- 组件
    Text to image论文精读PDF-GAN:文本生成图像新度量指标SSD Semantic Similarity Distance
    计算机网络 5 - 链路层
  • 原文地址:https://blog.csdn.net/weixin_67465673/article/details/126431067