SpringMVC之JSR303和拦截器

目录

一、JSR303

1.1 什么是JSR303

1.2 为什么要使用JSR303

1.3 常用注解

1.4 快速入门

1.4.1 导入依赖

1.4.2 配置校验规则

1.4.3 入门案例

二、拦截器

2.1 什么是拦截器

2.1.1 定义

2.1.2 作用领域 

2.2 过滤器

2.2.1 定义

2.2.2 作用领域

2.3 拦截器与过滤器的区别

2.4 应用场景

2.5 快速入门

2.5.1 入门案例

2.5.2 拦截器工作原理 

2.6 拦截器链

2.7 用户登录权限控制


一、JSR303

1.1 什么是JSR303

JSR303是Java规范请求(Java Specification Request)的编号,它定义了Java Bean验证的标准。Java Bean验证是一种验证框架,可以验证Java Bean中的属性,以确保它们符合特定的规则和约束。该框架在Java EE 6中得到了官方支持,并在javax.validation包中实现。JSR303规范定义了验证注释,这些注释可以应用于Java Bean的属性上,以指示验证规则。这些验证规则可以检查属性是否为空、是否符合正则表达式、是否在指定范围内等等。通过使用JSR303,我们可以确保Java Bean的属性始终符合预期,并在出现错误时及时捕获并处理这些错误。

JSR303的定义:

JSR303是一种Java平台标准,也称为Bean Validation,用于验证JavaBean和其他Java对象的声明约束。JSR303使用注释标记属性的限制,并提供了一个验证引擎,该引擎可以在运行时执行验证以确保对象的有效性。它提供了一种轻松的方式来验证表单数据和其他用户输入,防止不良数据进入应用程序。JSR303旨在提供一致的验证机制,使Java应用程序更加健壮和可维护。

1.2 为什么要使用JSR303

JSR303是Java Validation API的规范,它提供了一种简单易用的验证框架,帮助我们在实体类属性上进行验证,对于确保数据的正确性和完整性非常有用。 使用JSR303可以带来以下好处:

1. 易于维护和扩展:将验证规则注解到属性上,代码易于维护和扩展,避免了繁琐的手工验证。

2. 提高代码可读性:验证规则注解到属性上,代码可读性大大提高。

3. 减少重复代码:使用JSR303可以减少编写检验代码的重复工作,提高生产效率。

4. 提高系统健壮性:通过JSR303验证规则的定义,可以确保数据的正确性和完整性,提高系统健壮性和稳定性。

1.3 常用注解

JSR303是Java中的Bean Validation规范,其中定义了许多注解用于对JavaBean中的属性进行验证。以下是常用的JSR303注解及其解释:

1. @NotNull:验证字段不为null。

2. @NotBlank:验证字段不为空,即长度大于0,去掉空格后长度大于0。

3. @NotEmpty:验证字段不为空,即长度大于0。

4. @Min:验证数字字段的最小值。

5. @Max:验证数字字段的最大值。

6. @Size:验证字段的大小范围。

7. @DecimalMin:验证十进制数字段的最小值。

8. @DecimalMax:验证十进制数字段的最大值。

9. @Pattern:验证字段匹配正则表达式。

10. @Email:验证字段为Email格式。

11. @Length:验证字段的长度。

12. @Range:验证字段的值在范围内。

13. @Valid:验证嵌套对象。

14. @AssertTrue:验证字段为true。

15. @AssertFalse:验证字段为false。

16. @Past:验证日期字段在当前时间之前。

17. @Future:验证日期字段在当前时间之后。

以上是常用的JSR303注解及其解释,开发者可以根据实际情况选择需要的注解。

@Validated与@Valid区别 ::

@Validated:

  • Spring提供的

  • 支持分组校验

  • 可以用在类型、方法和方法参数上。但是不能用在成员属性(字段)上

  • 由于无法加在成员属性(字段)上,所以无法单独完成级联校验,需要配合@Valid

@Valid:

  • JDK提供的(标准JSR-303规范)

  • 不支持分组校验

  • 可以用在方法、构造函数、方法参数和成员属性(字段)上

  • 可以加在成员属性(字段)上,能够独自完成级联校验

1.4 快速入门

1.4.1 导入依赖


6.0.7.Final



    org.hibernate
    hibernate-validator
    ${hibernate.validator.version}

1.4.2 配置校验规则

校验属性是否为空:

 @NotNull(message = "歌曲编号不能为空")
    private Integer mid;
    @NotBlank(message = "歌曲名称不能为空")
    private String mname;
    @NotBlank(message = "歌曲专辑不能为空")
    private String mtype;
    @NotBlank(message = "歌曲歌词不能为空")
    private String minfo;
    @NotBlank(message = "歌曲图片不能为空")
    private String mpic = "暂无图片";

1.4.3 入门案例

在MusicController类中添加以下方法:

 //    给数据添加服务端校验
    @RequestMapping("/valiAdd")
    public String valiAdd(@Validated Music music, BindingResult result, HttpServletRequest req){
//        如果服务端验证不通过,有错误
        if(result.hasErrors()){
//            服务端验证了实体类的多个属性,多个属性都没有验证通过
            List fieldErrors = result.getFieldErrors();
            Map map = new HashMap<>();
            for (FieldError fieldError : fieldErrors) {
//                将多个属性的验证失败信息输送到控制台
                System.out.println(fieldError.getField() + ":" + fieldError.getDefaultMessage());
                map.put(fieldError.getField(),fieldError.getDefaultMessage());
            }
            req.setAttribute("errorMap",map);
        }else {
            this.musicBiz.insertSelective(music);
            return "redirect:list";
        }
        return "mic/edit";
    }

在服务端中进行校验,校验的模型的属性中出现错误,则将错误信息的属性进行遍历添加到map集合中并保存起来回显到前端,需要注意的是,注解@validated保存的是校验时的参数,最终校验的结果保存在BindingResult中.

1.4.4 结果测试

在没有进行后端效验前应该会报空指针异常。

但是在进行后端效验之后,就会将我们的错误信息反馈到前端的展示界面,如下:

SpringMVC之JSR303和拦截器_第1张图片

控制台效果:

SpringMVC之JSR303和拦截器_第2张图片

 

二、Java三大器之拦截器

2.1 什么是拦截器

2.1.1 定义

在Java编程中,拦截器(Interceptor)是一种常见的机制,它可以拦截方法的调用或者HTTP请求的处理过程,并在处理前后执行一些特定的操作或者逻辑。拦截器通常用于实现各种不同的功能,如权限控制、日志记录、事务管理等。

2.1.2 作用领域 

在Java Web开发中,拦截器常用于拦截HTTP请求并进行处理,例如进行身份验证、拦截非法的请求、记录日志等。在Spring框架中,拦截器是一个非常重要的组件,可以通过实现HandlerInterceptor接口来定义拦截器,然后在配置文件中配置拦截器的拦截规则和执行顺序。在Struts2、Spring MVC等Web框架中也都有拦截器的支持。

2.2 Java三大器之过滤器

2.2.1 定义

Java中的过滤器(Filter)是一种用于拦截HTTP请求和响应的组件,它在请求到达Servlet之前拦截并验证HTTP请求,或在Servlet响应到达客户端前对响应进行处理。在Java Web应用中,过滤器是一个可配置的组件,它需要在web.xml文件中注册并配置相应的属性才能生效。可以通过编写实现javax.servlet.Filter接口的Java类来定义过滤器的功能。

2.2.2 作用领域

过滤器通常用于实现一些通用的处理逻辑,比如认证、日志记录、统计信息等,以提高代码复用性和可维护性。过滤器还可以用于跨站点脚本攻击(XSS)和跨站点请求伪造(CSRF)等安全机制的实现。 

2.3 拦截器与过滤器的区别

图解如下:

SpringMVC之JSR303和拦截器_第3张图片

拦截器和过滤器都是在Java Web开发中对请求进行拦截处理的一种工具,但是它们有以下区别:

1. 执行顺序: 过滤器是在Servlet容器调用servlet之前或之后执行的,而拦截器是在servlet处理请求之前或之后执行的。

2. 作用范围: 过滤器作用于所有的请求和响应,包括静态资源,而拦截器只拦截配置的路径及其子路径的请求。

3. 功能范围: 过滤器可以在过滤器链中做一些额外的功能,如字符编码、请求转发和重定向等,而拦截器可以更好地控制业务流程,如权限控制、日志记录等。

4. API不同: 过滤器是使用Servlet API实现的,而拦截器是使用Spring MVC框架自身的接口实现的。

总的来说,过滤器更加通用,可以实现一些基本的请求过滤和处理操作,而拦截器则更加灵活,可以根据业务需求实现更加复杂的操作。在实际应用中,需要根据具体的需求选择使用过滤器还是拦截器。 

2.4 应用场景

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

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

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

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

 2.5 拦截器工作原理 

SpringMVC之JSR303和拦截器_第4张图片

2.6 用户登录权限控制

基本拦截器配置(在Java目录下新建一个interceptor包,创建拦截器类):

OneInterceptor:

package com.Kissship.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 OneInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("【OneInterceptor】:preHandle...");
 
        return true;
    }
 
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("【OneInterceptor】:postHandle...");
 
    }
 
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("【OneInterceptor】:afterCompletion...");
    }
}

TwoInterceptor:

package com.Kissship.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 TwoInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("【TwoInterceptor】:preHandle...");
 
        return true;
    }
 
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("【TwoInterceptor】:postHandle...");
 
    }
 
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("【TwoInterceptor】:afterCompletion...");
    }
}

然后在Spring-mvc.xml中配置多拦截器,添加代码如下:

 
    
        
    

    
        
        
            
            
        
        
            
            
        
    

然后接下来创建一个名为LoginInterceptor的拦截器,如下:

package com.Kissship.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 LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("【implements】:preHandle...");
        StringBuffer url = request.getRequestURL();
        if (url.indexOf("/login") > 0 || url.indexOf("/logout") > 0){
            //        如果是 登录、退出 中的一种
            return true;
        }
//            代表不是登录,也不是退出
//            除了登录、退出,其他操作都需要判断是否 session 登录成功过
        String mname = (String) request.getSession().getAttribute("mname");
        if (mname == null || "".equals(mname)){
            response.sendRedirect("/page/login");
            return false;
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}

接着创建一个新的jsp页面用来充当登录界面进行效果测试,login.jsp代码如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    用户登入




最后进行测试,效果如下:

SpringMVC之JSR303和拦截器_第5张图片


最后SpringMVC之JSR303和拦截器就到这里,祝大家在敲代码的路上一路通畅!

感谢大家的观看 !

SpringMVC之JSR303和拦截器_第6张图片

你可能感兴趣的:(java,开发语言)