• JSR303和拦截器


    目录

    一、JSR303

    二、拦截器


    一、JSR303

    1、服务端验证

    1.1 导入pom依赖



       org.hibernate 
       hibernate-validator
       6.0.7.Final

    1.2 对实体类进行约束

    1. package com.zxw.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. @NotBlank(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. }

    注:

    @NotNull :作用于基本数据类型
    @NotEmpty    作用于集合
    @NotBlank    作用于字符串

    1.3 ClazzController:

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

    1.4 clzEdit

    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. <%--
    11. <form action="${pageContext.request.contextPath }/clz/${empty b ? 'add' : 'edit'}" method="post">
    12. --%>
    13. <form action="${pageContext.request.contextPath }/clz/${empty b ? 'valiAdd' : 'edit'}" method="post">
    14. cid:<input type="text" name="cid" value="${b.cid }"><span style="color: pink;">${msg.cid}</span><br>
    15. cname:<input type="text" name="cname" value="${b.cname }"><span style="color: pink;">${msg.cname}</span><br>
    16. cteacher:<input type="text" name="cteacher" value="${b.cteacher }"><span style="color: pink;">${msg.cteacher}</span><br>
    17. <input type="submit">
    18. </form>
    19. </body>
    20. </html>

    测试:

    若没有任何信息 点击提交 我们的验证就会提示

     

    若填写了 则相反

    二、拦截器

    2.1什么是拦截器?

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

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

    2.2 拦截器与过滤器的区别

     过滤器(filter):

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

        拦截器(interceptor)

        1、interceptor属于SpringMVC技术,必须要有SpringMVC环境才可以使用
        2、interceptor通常对处理器Controller进行拦截
        3、interceptor只能拦截dispatcherServlet处理的请求

    2.3 拦截器说明方法

      preHandle方法
        作用:用于对拦截到的请求进行预处理,方法接收布尔(true,false)类型的返回值,返回true:放行,false:不放行。
        执行时机:在处理器方法执行前执行 
        方法参数:
        1)request请求对象
        2)response响应对象
        3)handler拦截到的方法处理

        postHandle方法
        作用:用于对拦截到的请求进行后处理,可以在方法中对模型数据和视图进行修改
        执行时机:在处理器的方法执行后,视图渲染之前
        方法参数:
        1)request请求对象
        2)response响应对象
        3)handler拦截到的处理器方法
        4)ModelAndView处理器方法返回的模型和视图对象,可以在方法中修改模型和视图

        afterCompletion方法
        作用:用于在整个流程完成之后进行最后的处理,如果请求流程中有异常,可以在方法中获取对象
        执行时机:视图渲染完成后(整个流程结束之后)
        方法参数:
        1)request请求参数
        2)response响应对象
        3)handler拦截到的处理器方法
        4)ex异常对象

    2.4 拦截器使用步骤

    1、实现HandlerInterceptor接口  对应实现三个方法

    2、完成springmvc.xml中的配置

    2.5 应用场景

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

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

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

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

    OneHandlerInterceptor:
    1. package com.zxw.ssm.intercept;
    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 zxw
    8. * @site ......
    9. * @company 好男人
    10. * @create  2022-08-20 9:19
    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. String url = request.getRequestURL().toString();
    19. if(url.indexOf("/login") > 0 || url.indexOf("/logout") > 0){
    20. return true;
    21. }
    22. // 对于请求业务方法 只有登录过也就是存在session数据 才能访问
    23. String uname = (String) request.getSession().getAttribute("uname");
    24. if (uname == null || "".equals(uname)) {
    25. response.sendRedirect("login.jsp");
    26. return false;
    27. }
    28. return true;
    29. }
    30. @Override
    31. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    32. // 后处理
    33. System.out.println("[OneHandlerInterceptor] . postHandle...");
    34. }
    35. @Override
    36. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    37. // 完成后执行
    38. System.out.println("[OneHandlerInterceptor] . afterCompletion...");
    39. }
    40. }

    springmvc.xml配置:

    
          <!–        针对于所有的请求进行拦截–>
          
      

    测试类HelloController:

    二、拦截器链 

    创建另一个拦截器

    1. package com.zxw.ssm.intercept;
    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 zxw
    8. * @site ......
    9. * @company 好男人
    10. * @create  2022-08-20 9:19
    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.xml配置:

    1. <!-- 配置拦截器链-->
    2. <mvc:interceptors>
    3. <mvc:interceptor>
    4. <mvc:mapping path="/**"/>
    5. <bean class="com.zxw.ssm.intercept.OneHandlerInterceptor"></bean>
    6. </mvc:interceptor>
    7. <mvc:interceptor>
    8. <mvc:mapping path="/clz/**"/>
    9. <bean class="com.zxw.ssm.intercept.TwoHandlerInterceptor"></bean>
    10. </mvc:interceptor>
    11. </mvc:interceptors>

    测试:

  • 相关阅读:
    【深度学习】浅显易懂的残差网络(Residual Network)
    5.5 框架程序的执行顺序
    html网页制作期末大作业成品:基于HTML+CSS+JavaScript简洁汽车网站(7页)
    中台框架模块开发实践-代码生成器的添加及使用
    java旋转base64位,自定义旋转角度角度
    低代码平台简单分享
    ElasticSearch-Query DSL(Domain Specific Language)
    vue中keep-alive怎么清除组件的缓存
    测试开发日记:locust压测带你小试牛刀
    Flink Hudi DataStream API代码示例
  • 原文地址:https://blog.csdn.net/m0_62327548/article/details/126437239