ConstraintValidator类如何实现自定义注解校验前端传参

要实现自定义注解校验前端传参,需要使用到Java中的ConstraintValidator类。以下是实现的步骤:

  1. 创建自定义注解

首先需要创建一个自定义注解,并定义需要校验的参数和校验条件。下面的示例定义了一个名为CheckPassword的注解,用来校验密码是否符合规定的长度和包含数字、字母和特殊字符:

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;

@Documented
@Constraint(validatedBy = PasswordValidator.class)
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface CheckPassword {
    String message() default "Invalid password format";
    int minLength() default 6;
    int maxLength() default 20;
    boolean needNumber() default true;
    boolean needLowerCase() default true;
    boolean needUpperCase() default true;
    boolean needSpecialChar() default true;
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}
  1. 创建校验器

通过实现ConstraintValidator接口,我们可以自定义校验逻辑,并将其与注解绑定起来。以下是实现PasswordValidator校验器的示例代码:

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.regex.Pattern;

public class PasswordValidator implements ConstraintValidator<CheckPassword, String> {
    private int minLength;
    private int maxLength;
    private boolean needNumber;
    private boolean needLowerCase;
    private boolean needUpperCase;
    private boolean needSpecialChar;

    @Override
    public void initialize(CheckPassword constraintAnnotation) {
        this.minLength = constraintAnnotation.minLength();
        this.maxLength = constraintAnnotation.maxLength();
        this.needNumber = constraintAnnotation.needNumber();
        this.needLowerCase = constraintAnnotation.needLowerCase();
        this.needUpperCase = constraintAnnotation.needUpperCase();
        this.needSpecialChar = constraintAnnotation.needSpecialChar();
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if (value == null || value.isEmpty()) {
            return true; // empty value is valid
        }
        if (value.length() < minLength || value.length() > maxLength) {
            return false;
        }
        if (needNumber && !Pattern.compile("[0-9]").matcher(value).find()) {
            return false;
        }
        if (needLowerCase && !Pattern.compile("[a-z]").matcher(value).find()) {
            return false;
        }
        if (needUpperCase && !Pattern.compile("[A-Z]").matcher(value).find()) {
            return false;
        }
        if (needSpecialChar && !Pattern.compile("[!\"#$%&'()*+,-./:;<=>?@\\[\\\\\\]^_`{|}~]").matcher(value).find()) {
            return false;
        }
        return true;
    }
}

initialize()方法中,我们可以获得注解的参数,以便根据不同的参数设置不同的校验规则。isValid()方法是校验逻辑的核心,返回true表示参数符合要求,而返回false则表示参数不符合要求。

  1. 在Controller中使用自定义注解

当我们需要校验某个Controller方法中的参数时,只需在参数上使用自定义的注解即可。例如,以下示例中的registerUser()方法就使用了CheckPassword注解对密码进行了校验:

import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api")
@Validated // enable validation globally
public class UserController {
    @PostMapping("/register")
    public ResponseEntity<String> registerUser(
            @RequestParam String username,
            @CheckPassword @RequestParam String password,
            @RequestParam String email) {
        // do something...
    }
}

@CheckPassword注解之前加上@Validated注解,可以启用全局参数校验。这样,当前端使用HTTP POST方法调用/api/register接口时,就会对password参数进行校验。如果校验失败,将返回HTTP状态码为400的错误响应,其中包含一个错误消息,消息内容为自定义注解中message属性指定的内容。

  1. 示例说明

示例1:校验数字验证码

对于一个需要使用短信验证码的场景,当我们想要验证用户输入的短信验证码是否正确时,就可以使用自定义注解来实现。定义一个名为CheckSmsCode的注解,用于验证短信验证码是否正确:

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;

@Documented
@Constraint(validatedBy = SmsCodeValidator.class)
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface CheckSmsCode {
    String message() default "Invalid sms code";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

定义SmsCodeValidator校验器,用于校验短信验证码是否正确:

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

public class SmsCodeValidator implements ConstraintValidator<CheckSmsCode, String> {
    @Override
    public void initialize(CheckSmsCode constraintAnnotation) {
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        // validate sms code here
        return false; // TODO: implement this
    }
}

在Controller中使用自定义注解:

import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api")
@Validated // enable validation globally
public class SmsController {
    @PostMapping("/verify")
    public ResponseEntity<String> verifySmsCode(
            @RequestParam String phone,
            @CheckSmsCode @RequestParam String smsCode) {
        // do something...
    }
}

示例2:校验密码强度

对于一个需要使用复杂密码的场景,当我们想要验证用户输入的密码是否符合要求时,也可以使用自定义注解来实现。定义一个名为CheckPassword的注解,用于验证密码是否符合要求:

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;

@Documented
@Constraint(validatedBy = PasswordValidator.class)
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface CheckPassword {
    String message() default "Invalid password format";
    int minLength() default 6;
    int maxLength() default 20;
    boolean needNumber() default true;
    boolean needLowerCase() default true;
    boolean needUpperCase() default true;
    boolean needSpecialChar() default true;
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

定义PasswordValidator校验器,用于校验密码强度是否符合要求:

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.regex.Pattern;

public class PasswordValidator implements ConstraintValidator<CheckPassword, String> {
    private int minLength;
    private int maxLength;
    private boolean needNumber;
    private boolean needLowerCase;
    private boolean needUpperCase;
    private boolean needSpecialChar;

    @Override
    public void initialize(CheckPassword constraintAnnotation) {
        this.minLength = constraintAnnotation.minLength();
        this.maxLength = constraintAnnotation.maxLength();
        this.needNumber = constraintAnnotation.needNumber();
        this.needLowerCase = constraintAnnotation.needLowerCase();
        this.needUpperCase = constraintAnnotation.needUpperCase();
        this.needSpecialChar = constraintAnnotation.needSpecialChar();
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if (value == null || value.isEmpty()) {
            return true; // empty value is valid
        }
        if (value.length() < minLength || value.length() > maxLength) {
            return false;
        }
        if (needNumber && !Pattern.compile("[0-9]").matcher(value).find()) {
            return false;
        }
        if (needLowerCase && !Pattern.compile("[a-z]").matcher(value).find()) {
            return false;
        }
        if (needUpperCase && !Pattern.compile("[A-Z]").matcher(value).find()) {
            return false;
        }
        if (needSpecialChar && !Pattern.compile("[!\"#$%&'()*+,-./:;<=>?@\\[\\\\\\]^_`{|}~]").matcher(value).find()) {
            return false;
        }
        return true;
    }
}

在Controller中使用自定义注解:

import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api")
@Validated // enable validation globally
public class UserController {
    @PostMapping("/register")
    public ResponseEntity<String> registerUser(
            @RequestParam String username,
            @CheckPassword @RequestParam String password,
            @RequestParam String email) {
        // do something...
    }
}

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:ConstraintValidator类如何实现自定义注解校验前端传参 - Python技术站

(0)
上一篇 2023年5月29日
下一篇 2023年5月29日

相关文章

  • vue使用axios导出后台返回的文件流为excel表格详解

    下面是详细讲解“vue使用axios导出后台返回的文件流为excel表格”的攻略。 1. 准备工作 首先,我们需要准备一些工作。这些工作包括: 安装vue和axios库 安装js-xlsx库(用于处理excel文件) 后台返回的文件流是excel格式 后台需要返回file流类型,不能直接返回json 2. 导出excel表格 前端代码示例: <temp…

    Vue 2023年5月27日
    00
  • Vue.js每天必学之方法与事件处理器

    Vue.js每天必学之方法与事件处理器 Vue.js是一款流行的JavaScript框架,可以用于构建现代化、高效的Web应用程序。学习Vue.js需要熟悉其核心概念和常用方法,其中事件处理器是重点之一。本文将结合示例详细讲解Vue.js中的方法与事件处理器。 Vue.js中的方法 Vue.js提供了许多内置方法,用于处理组件的生命周期、渲染、数据传递等。以…

    Vue 2023年5月28日
    00
  • 详解VUE单页应用骨架屏方案

    标题:详解VUE单页应用骨架屏方案 什么是骨架屏 骨架屏即为页面骨架,通俗点来说就是一个页面还没加载完成时,所出现的一种页面展示方案。它将页面大致的结构和样式提前定义好,填充占位元素在视觉上证明了页面正在加载。而实际上用户看到的只是一个假象,等待页面正式加载完成后,占位元素会被替换成真实的内容。 骨架屏在VUE单页应用中的应用 在VUE单页应用中,页面通过异…

    Vue 2023年5月28日
    00
  • 你可能不知道的typescript实用小技巧

    作为 Typescript 常见的使用者,也许你已经对它的一些语法特性熟悉,但是,你可能不知道的 Typescript 实用小技巧可不止这些。接下来我将为你讲解一些不太为人所知的 Typescript 实用小技巧,希望能够对你的开发带来帮助。 1. 类型断言(Type Assertion) 类型断言是一种告诉编译器更确切的类型信息的方式,它可以强制类型检查器…

    Vue 2023年5月28日
    00
  • vue源码中的检测方法的实现

    Vue源码中的检测方法的实现使用的是JavaScript提供的Object.defineProperty()方法,它可以拦截对对象属性的访问和修改。Vue将此方法用于Vue实例的data对象和组件实例的props对象上,以便在属性值变化时可以感知到,并及时更新视图。 具体实现步骤如下: 实现一个观察者,用来监听对象的变化,当对象的某个属性发生变化时,观察者会…

    Vue 2023年5月27日
    00
  • Vue3中reactive函数toRef函数ref函数简介

    下面是“Vue3中reactive函数toRef函数ref函数简介”的完整攻略: 1. reactive函数 reactive 是 Vue.js 组件开发中一个常用的函数,它可以将一个普通的 JavaScript 对象转换成一个响应式的数据对象,在对象发生变化时,会自动更新对应的视图。 举个例子,假设有一个计数器,初始值为0,我们可以这样用 reactive…

    Vue 2023年5月28日
    00
  • Vue加载json文件的方法简单示例

    下面是“Vue加载json文件的方法简单示例”的完整攻略: 1. 安装 axios 为了能方便地加载JSON文件,我们需要安装axios,它是一个基于Promise的HTTP库,可以用于浏览器和Node.js。我们可以使用npm进行安装,命令如下: npm install axios –save 2. 创建一个JSON文件 为了演示如何通过Vue加载JSO…

    Vue 2023年5月28日
    00
  • 一篇超详细的Vue-Router手把手教程

    一篇超详细的Vue-Router手把手教程 简介 Vue-Router是Vue.js官方提供的用于路由管理的插件,可以帮助我们快速地构建单页应用。本文将从基础的使用开始,逐步深入解析Vue-Router的特性和使用方法,让你轻松掌握Vue-Router的使用。 基本使用 安装 使用npm安装Vue-Router: npm install vue-router…

    Vue 2023年5月27日
    00
合作推广
合作推广
分享本页
返回顶部