• SpringMVCJSR303和拦截器


    目录

    本次目标:

    一、JSR303

            1.1 JSR303的作用:

            1.2 pom依赖

            1.3.后端

                    Clazz.java实体类

                    控制层ClazzController.java

            1.4 前端

                    clzEdit.jsp

    二、拦截器

    2.1 什么是拦截器

    2.2 拦截器与过滤器

            2.2.1 什么是过滤器(Filter) 

            2.2.2 拦截器与过滤器的区别

    2.3 应用场景

     2.4 举例说明

    2.5 拦截器链 


    本次目标:

    1. JSR303
    2. 拦截器

    一、JSR303

            1.1 JSR303的作用:

                    服务端的验证

            1.2 pom依赖

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

            1.3.后端

                    Clazz.java实体类

    1. package com.ps.ssm.model;
    2. import javax.validation.constraints.NotBlank;
    3. import javax.validation.constraints.NotNull;
    4. /**
    5. * @NotNull :作用于基本数据类型
    6. * @NotEmpty 作用于集合
    7. * @NotBlank 作用于字符串
    8. */
    9. public class Clazz {
    10. @NotNull(message = "班级编号不能为空")
    11. // @Size(max = 100,min = 10,message = "大小必须在10至100之间")
    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. }

                    控制层ClazzController.java

    1. // 给数据添加服务端校验
    2. @RequestMapping("/valiAdd")
    3. public String valiAdd(@Validated Clazz clazz, BindingResult result,HttpServletRequest req){
    4. // 如果服务端验证不通过,有错误
    5. if(result.hasErrors()){
    6. // 服务端验证了实体类的多个属性,多个属性都没有验证通过
    7. List fieldErrors = result.getFieldErrors();
    8. Map map = new HashMap<>();
    9. for (FieldError fieldError : fieldErrors) {
    10. // 将多个属性的验证失败信息输送到控制台
    11. System.out.println(fieldError.getField() + ":" + fieldError.getDefaultMessage());
    12. map.put(fieldError.getField(),fieldError.getDefaultMessage());
    13. }
    14. req.setAttribute("errorMap",map);
    15. }else {
    16. this.clazzBiz.insertSelective(clazz);
    17. return "redirect:/clz/list";
    18. }
    19. return "clzEdit";
    20. }

            1.4 前端

                    clzEdit.jsp

    1. <body>
    2. <%--<form action="${pageContext.request.contextPath }/clz/${empty b ? 'add' : 'edit'}" method="post">--%>
    3. <form action="${pageContext.request.contextPath }/clz/${empty b ? 'valiAdd' : 'edit'}" method="post">
    4. id:<input type="text" name="cid" value="${b.cid }"><span style="color: red;">${errorMap.cid}span><br>
    5. cname:<input type="text" name="cname" value="${b.cname }"><span style="color: red;">${errorMap.cname}span><br>
    6. cteacher:<input type="text" name="cteacher" value="${b.cteacher }"><span style="color: red;">${errorMap.cteacher}span><br>
    7. <input type="submit">
    8. form>
    9. body>

    二、拦截器

    2.1 什么是拦截器

    1. SpringMVC的处理器拦截器,类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。
    2.   依赖于web框架,在实现上基于Java的反射机制,属于面向切面编程(AOP)的一种运用。由于拦截器是基于
    3.   web框架的调用,因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个 
    4.   controller生命周期之内可以多次调用。

    2.2 拦截器与过滤器

            2.2.1 什么是过滤器(Filter) 

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

            2.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 应用场景

    1. 日志记录:记录请求信息的日志,以便进行信息监控、信息统计、计算PV(Page View)等。
    2. 权限检查:如登录检测,进入处理器检测是否登录,如果没有直接返回到登录页面;
    3. 性能监控:有时候系统在某段时间莫名其妙的慢,可以通过拦截器在进入处理器之前  记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间(如果有反向代理,如apache可以自动记录);
    4. 通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Locale、Theme信息等,只要是多个Controller中的处理方法都需要的,我们就可以使用拦截器实现。

     2.4 举例说明

     写一个类  创建HelloController,创建自定义拦截器并实现HandlerInterceptor接口。

    1. @Controller
    2. public class HelloController {
    3. @RequestMapping("/hello")
    4. public String hello(){
    5. System.out.println("come in hello.jsp");
    6. return "index";
    7. }
    8. }
    9. public class OneInterceptor implements HandlerInterceptor {
    10. @Override
    11. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    12. System.out.println("【OneInterceptor】:preHandle...");
    13. return true;
    14. }
    15. @Override
    16. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    17. System.out.println("【OneInterceptor】:postHandle...");
    18. }
    19. @Override
    20. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    21. System.out.println("【OneInterceptor】:afterCompletion...");
    22. }
    23. }
    1. <mvc:interceptors>
    2. <bean class="com.ps.ssm.interceptor.OneInterceptor">bean>
    3. mvc:interceptors>

    OneHandlerInterceptor 

    1. package com.ps.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. public class OneHandlerInterceptor implements HandlerInterceptor {
    7. @Override
    8. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    9. //预处理
    10. System.out.println("【OneInterceptor】:preHandle...");
    11. return true;
    12. }
    13. @Override
    14. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    15. //后处理
    16. System.out.println("【OneInterceptor】:postHandle...");
    17. }
    18. @Override
    19. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    20. //完成后执行
    21. System.out.println("【OneInterceptor】:afterCompletion...");
    22. }
    23. }

    运行:

     

    2.5 拦截器链 

    概念:

    如果多个拦截器能够对相同的请求进行拦截,则多个拦截器会形成一个拦截器链,主要理解拦截器链中各个拦截器的执行顺序。

    拦截器链中多个拦截器的执行顺序,根拦截器的配置顺序有关,先配置的先执行。

    springmvc-servlet.xml

    1. <mvc:interceptors>
    2. <mvc:interceptor>
    3. <mvc:mapping path="/**"/>
    4. <bean class="com.ps.ssm.intercept.OneHelloController">bean>
    5. mvc:interceptor>
    6. <mvc:interceptor>
    7. <mvc:mapping path="/clz/**"/>
    8. <bean class="com.ps.ssm.intercept.TwoHelloController">bean>
    9. mvc:interceptor>
    10. mvc:interceptors>

    TwoHandlerInterceptor.java

    1. package com.ps.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 彭于晏
    8. * @site www.yuyuan.com
    9. * @create 2022-08-20 00:49
    10. */
    11. public class TwoHandlerInterceptor implements HandlerInterceptor {
    12. @Override
    13. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    14. //预处理
    15. System.out.println("【TwoHandlerInterceptor】:preHandle...");
    16. return true;
    17. }
    18. @Override
    19. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    20. //后处理
    21. System.out.println("【TwoHandlerInterceptor】:postHandle...");
    22. }
    23. @Override
    24. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    25. //完成后执行
    26. System.out.println("【TwoHandlerInterceptor】:afterCompletion...");
    27. }
    28. }

    测试步骤如下:

    http://localhost:8080/clz/list 不能访问,因为session被过滤掉

    http://localhost:8080/login  不能访问,因为用户未成功登录被过滤掉

    http://localhost:8080/login?uname=zs 可以访问

    http://localhost:8080/logout 清除掉session

    输入 http://localhost:8080/login?uname=zs 的测试结果:

     今天的分享就到这里,我们下次再见!

  • 相关阅读:
    用ChatGPT做数据分析,提升10倍工作效率
    设计模式:访问者模式
    python opencv 读取文件夹下所有MP4文件并解析成jpg图像
    Echarts设置饼状图保证你看的明明白白
    认证服务-SpringSecurity及Oauth2介绍
    基于粒子群优化算法的UAV三维路径规划研究付Matlab代码
    竟然还有人说ArrayList是2倍扩容,今天带你手撕ArrayList源码
    js中创建对象的5种方法
    bash一行输入,多行回显demo脚本
    NoSQL之Redis配置与优化
  • 原文地址:https://blog.csdn.net/weixin_63531940/article/details/126434632