超详细关于JSR303服务端校验&&拦截器入门到案例使用

目录

一、JSR303

        1.1 JSR303的简介

        1.2 JSR303实现判空校验

二、拦截器

        2.1 什么是拦截器?

        2.2 建立一个拦截器

                2.2.1 配置拦截器

                2.2.2 拦截器方法的执行顺序

        2.3 建立拦截器链

                2.3.1 配置拦截器链

                2.3.2 拦截器链方法的执行顺序

        2.4 利用拦截器实现登录权限控制

                2.4.1 编写LoginController

                2.4.2 登录页面

                2.4.3 编写拦截器

                2.4.4 配置拦截器


一、JSR303

        1.1 JSR303的简介

                什么是JSR303?

JSR303是一个:{---服务端校验---}
它的作用:
解决了越过表单验证{客户端},直接访问页面的问题;

        1.2 JSR303实现判空校验

                我们通过上机实操来认识一下JSR303,实现的一些步骤:

                ① 导入pom依赖

    
      org.hibernate
      hibernate-validator
      6.0.7.Final
    

                ② 在待校验的数据库列段对应的实体类属性打上校验标签:非空校验

三种注解验证: 
     * @NotNull:作用于基本数据类型
     * @NotEmpty:作用于集合
     * @NotBlank:作用于字符串

        实体类:Clazz.java 

package com.leaf.ssm.model;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;

/**
 * @NotNull:作用于基本数据类型
 * @NotEmpty:作用于集合
 * @NotBlank:作用于字符串
 */
public class Clazz {

    @NotNull(message = "cid不能为空")
    protected Integer cid;

    @NotBlank(message = "班级名称不能为空")
    protected String cname;

    @NotBlank(message = "教员老师不能为空")
    protected String cteacher;

    protected String pic;

    public Clazz(Integer cid, String cname, String cteacher, String pic) {
        this.cid = cid;
        this.cname = cname;
        this.cteacher = cteacher;
        this.pic = pic;
    }

    public Clazz() {
        super();
    }

    public Integer getCid() {
        return cid;
    }

    public void setCid(Integer cid) {
        this.cid = cid;
    }

    public String getCname() {
        return cname;
    }

    public void setCname(String cname) {
        this.cname = cname;
    }

    public String getCteacher() {
        return cteacher;
    }

    public void setCteacher(String cteacher) {
        this.cteacher = cteacher;
    }

    public String getPic() {
        return pic;
    }

    public void setPic(String pic) {
        this.pic = pic;
    }
}

        ③ 在controller层方法上添加@Valid注解配合前面的校验标签;
            添加BindingResult,此对象包含所有校验为通过的错误信息;

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

总的来说就是编写一个用来校验的方法:

valiAdd(@Valid Clazz clazz, BindingResult bindingResult,HttpServletRequest request)

    /**
     * 校验的方法(演示校验注解)
     * @Valid:是与实体类中的服务端校验注解配合使用的
     * BindingResult:存放了所有违背校验的错误信息
     * @param clazz
     * @param bindingResult
     * @return
     */
    @RequestMapping("/valiAdd")
    public String valiAdd(@Valid Clazz clazz, BindingResult bindingResult,HttpServletRequest request){
        if(bindingResult.hasErrors()){//违背了规则
            HashMap msg = new HashMap();
            //拿到所有错误
            List fieldErrors = bindingResult.getFieldErrors();
            for (FieldError fieldError : fieldErrors) {
                //cid:cid不能为空
                System.out.println(fieldError.getField() + ":" + fieldError.getDefaultMessage());
                //msg.put(cid, cid不能为空);
                msg.put(fieldError.getField(),fieldError.getDefaultMessage());
            }
            //如果出现了错误,应该将提示语显示在表单提示元素后方
            request.setAttribute("msg",msg);
            return "clzEdit";
        }else{//没有违背
            this.clazzBiz.insertSelective(clazz);
        }
        return "redirect:/clz/list";
    }

 接下来就让我们来测试一下是否成功校验啦:

 新增:

超详细关于JSR303服务端校验&&拦截器入门到案例使用_第1张图片

校验成功~

 超详细关于JSR303服务端校验&&拦截器入门到案例使用_第2张图片

 


二、拦截器

        2.1 什么是拦截器?

拦截器的初步认知:
          ① SpringMVC的处理器拦截器,依赖于web框架,在实现上基于Java的反射机制,

属于面向切面编程(AOP)的一种运用。
          ② 一个拦截器实例在一个controller生命周期之内可以多次调用。

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

        2.2 建立一个拦截器

                我们还是一样,通过上机实践、测试,才能去认识并掌握这些技术;

        我们先写一个可以访问的方法层:HelloController

package com.leaf.ssm.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * 测试
 * @author Leaf
 * @site 2977819715
 * @company 玉渊工作室
 * @create  2022-08-20 1:35
 */
@Controller
public class HelloController {

    @RequestMapping("hello")
    public String hello(){
        System.out.println("进入业务方法...");
        return "index";
    }

}

        建立一个拦截器:OneHandlerInterceptor.java

package com.leaf.ssm.intercept;

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

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

/**
 * @author Leaf
 * @site 2977819715
 * @company 玉渊工作室
 * @create  2022-08-20 1:27
 */
public class OneHandlerInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //预处理
        System.out.println("[OneHandlerInterceptor] . preHandle");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        //后处理
        System.out.println("[OneHandlerInterceptor] . postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        //完成后处理
        System.out.println("[OneHandlerInterceptor] . afterCompletion");
    }
}

                2.2.1 配置拦截器

                我们需要在springmvc的框架配置文件中配置上我们写的拦截器;

        
    	
        	
        	         	
            
    	

        然后我们直接运行测试访问:http://localhost:8080/hello超详细关于JSR303服务端校验&&拦截器入门到案例使用_第3张图片

                2.2.2 拦截器方法的执行顺序

                通过运行结果我们得到几个关于拦截器的结论:

我们拦截器实现的三个方法以及执行顺序分别是:

预处理:    [OneHandlerInterceptor] . preHandle
业务方法:进入业务方法...
后处理:    [OneHandlerInterceptor] . postHandle
完成后:    [OneHandlerInterceptor] . afterCompletion

        并且,预处理方法里返回的true或者false就代表能不能继续跳转页面执行; 

        2.3 建立拦截器链

                接着我们来看看拦截器链的概念

拦截器链的概念:

如果多个拦截器能够对相同的请求进行拦截,则多个拦截器会形成一个拦截器链;

主要理解拦截器链中各个拦截器的执行顺序。

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

我们再次建立一个拦截器:TwoHandlerInterceptor.java

package com.leaf.ssm.intercept;

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

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

/**
 * @author Leaf
 * @site 2977819715
 * @company 玉渊工作室
 * @create  2022-08-20 1:27
 */
public class TwoHandlerInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //预处理
        System.out.println("[TwoHandlerInterceptor] . preHandle");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        //后处理
        System.out.println("[TwoHandlerInterceptor] . postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        //完成后处理
        System.out.println("[TwoHandlerInterceptor] . afterCompletion");
    }
}

                2.3.1 配置拦截器链

                这里就要注意,已经有两个拦截器了,配置就也有所不一样了;

    
    
        	
            	
            		
        	

        	
            	
            		
        	
    

然后我们还是运行一下测试http://localhost:8080/hello超详细关于JSR303服务端校验&&拦截器入门到案例使用_第4张图片

 

                2.3.2 拦截器链方法的执行顺序

        不一样的还有它们的执行顺序,前面关于拦截链的一些介绍已经说明了,需要理解它的执行顺序,这里Leaf特意花了一张运行图,配合文字,希望对大家有帮助。

拦截器链的执行顺序:

先进第一个拦截器--->第二个拦截器--->...

①    [OneHandlerInterceptor] . preHandle
②    [TwoHandlerInterceptor] . preHandle
③    业务方法
④    [TwoHandlerInterceptor] . postHandle
⑤    [OneHandlerInterceptor] . postHandle
⑥    [TwoHandlerInterceptor] . afterComplation
⑦    [OneHandlerInterceptor] . afterComplation

运行草图: 超详细关于JSR303服务端校验&&拦截器入门到案例使用_第5张图片

        2.4 利用拦截器实现登录权限控制

                OK,上面的都是关于拦截器的理论知识以及一些打印的小测试,下面,我们就通过实际上的案例对拦截器进行使用!

                2.4.1 编写LoginController

                        LoginController.java

package com.leaf.ssm.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;

/**
 * @author Leaf
 * @site 2977819715
 * @company 玉渊工作室
 * @create  2022-08-20 2:25
 */
@Controller
public class LoginController {

    /**
     * 登录方法
     * @param request
     * @return
     */
    @RequestMapping("/login")
    public String login(HttpServletRequest request){
        //登录成功需要保存用户信息
        String uname = request.getParameter("uname");
        if("Leaf".equals(uname)){
            request.getSession().setAttribute("uname",uname);
        }
        return "index";
    }

    @RequestMapping("/logout")
    public String logout(HttpServletRequest request){
        request.getSession().invalidate();
        return "index";
    }

}

                2.4.2 登录页面

                就随便建立一个登录页面就行了:login.jsp

<%--
  Created by IntelliJ IDEA.
  User: Administrator
  Date: 2022/8/20
  Time: 2:30
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    登录页面


登录页面

                2.4.3 编写拦截器

                 这一步很重要,仔细看看代码,都有部分注释;

  OneHandlerInterceptor.java

package com.leaf.ssm.intercept;

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

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

/**
 * @author Leaf
 * @site 2977819715
 * @company 玉渊工作室
 * @create  2022-08-20 1:27
 */
public class OneHandlerInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //预处理
        System.out.println("[OneHandlerInterceptor] . preHandle");

        //拿到请求路径
        String url = request.getRequestURL().toString();
        //如果是 login/logout 访问,不拦截,直接放行。
        if (url.indexOf("/login") > 0 || url.indexOf("/logout") > 0){
            return true;
        }
        //对于请求业务方法,只有登录过,也就是存在session的数据,才能访问;
        String uname = (String) request.getSession().getAttribute("uname");
        if(uname == null || "".equals(uname)){
            //没有登录,跳回登录页面。
            response.sendRedirect("/login.jsp");
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        //后处理
        System.out.println("[OneHandlerInterceptor] . postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        //完成后处理
        System.out.println("[OneHandlerInterceptor] . afterCompletion");
    }
}

                2.4.4 配置拦截器

                这里注意了,由于是做登录的校验,拦截器,自然要拦截所有请求;

这里直接放上案例用的整个springmvc的框架配置文件吧!

springmvc-servlet.xml



    
    
    
    

    
    
    
    

    
    
        
        
        
        
    

    
    
    
    

    
    
        
        
        
        
        
        
    

    
    

    
    
        
            
            
        
        
    

测试:

        最后就让我们一起来测试一下吧,我们的登录信息是定死的Leaf,开始登录测试:超详细关于JSR303服务端校验&&拦截器入门到案例使用_第6张图片

拦截成功,登录失败: 超详细关于JSR303服务端校验&&拦截器入门到案例使用_第7张图片

输入正确的身份信息,登录成功: 超详细关于JSR303服务端校验&&拦截器入门到案例使用_第8张图片

超详细关于JSR303服务端校验&&拦截器入门到案例使用_第9张图片

 登录成功,测试完毕! 

你可能感兴趣的:(Spring,java,spring,mvc)