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学习笔记第一篇

    以下是关于“前端主流框架Vue学习笔记第一篇”的完整攻略: 1. 前言 Vue.js 是一个流行的开源 javascript 框架,用于构建用户界面(UI)和单页面应用程序(SPA)。Vue 以其易用性、速度和灵活性而著称,并且是当今业界最流行的前端框架之一。本笔记的目的是帮助新手快速入门并了解 Vue.js 的基础知识和核心概念。 2. 安装与使用 在学习…

    Vue 2023年5月28日
    00
  • ant design 日期格式化的实现

    Ant Design 日期格式化的实现 Ant Design 是蚂蚁金服开发的一套基于 React 的企业级 UI 组件库,其中包含了日期选择器和日期格式化工具。 日期格式化工具 Ant Design 中的日期格式化工具是基于 Moment.js 的 API 实现的。 Moment.js 是一个用于解析、验证、操作和显示日期以及时间的 JavaScript …

    Vue 2023年5月29日
    00
  • AntV+Vue实现导出图片功能

    AntV 是 Ant Design 团队出品的数据可视化解决方案,而 Vue 是当下广泛使用的前端框架之一。本文将介绍如何在 Vue 项目中使用 AntV 实现导出图片功能。具体实现流程如下: 1. 环境搭建 在 Vue 项目中使用 AntV,需要先安装 @antv/g2 和 @antv/data-set 两个依赖包: npm install @antv/g…

    Vue 2023年5月28日
    00
  • v-for循环中使用require/import关键字引入本地图片的几种方式

    关于“v-for循环中使用require/import关键字引入本地图片的几种方式”的攻略,我可以为您做出以下解释。 一、使用require导入图片 在Vue项目中,如果我们想要引入一张本地图片启用,我们可以使用require命令将图片导入。我们可以通过如下方法将图片导入到Vue程序中: <template> <div> <im…

    Vue 2023年5月28日
    00
  • vue再次进入页面不会再次调用接口请求问题

    Vue再次进入页面不会再次调用接口请求问题,主要是因为Vue实现了单页应用(SPA)的机制,它使用了Vue-router来处理路由,当我们切换路由时,Vue-router只会切换组件,而不会重新请求数据。下面是详细的解释和攻略过程。 1. Vue-router实现SPA Vue使用Vue-router来实现路由,Vue-router是Vue.js官方的路由管…

    Vue 2023年5月28日
    00
  • 使用 Jest 和 Supertest 进行接口端点测试实例详解

    使用 Jest 和 Supertest 进行接口端点测试是一种常见的自动化测试方式,有助于提高开发和测试效率,以下是具体的实例攻略。 准备工作 在开始测试之前,我们需要先安装相关的环境和库,具体包括: 安装 Node.js 在 Node.js 官网 https://nodejs.org/en/ 上下载对应的版本并安装。 创建项目 在命令行中通过 npm 命令…

    Vue 2023年5月28日
    00
  • Vue mockjs编写假数据并请求获取实现流程

    Vue MockJS是一款用于前端mock数据的工具。其可以模拟请求API返回假数据,用于前端开发时进行数据调试、测试。本文将详细介绍Vue MockJS编写假数据并请求获取的实现流程。 1. 安装Vue MockJS 在使用Vue MockJS之前,需要确保在项目中已经安装了Vue,接着可以通过npm或yarn来安装Vue MockJS。 # 使用npm进…

    Vue 2023年5月28日
    00
  • 如何配置vue.config.js 处理static文件夹下的静态文件

    下面是如何配置vue.config.js处理static文件夹下静态文件的完整攻略。 首先,需要明确一下vue-cli会默认将static文件夹里的文件拷贝到打包后的根目录中,并不会对其进行任何处理,因此我们需要配置vue.config.js来处理这些静态文件。 以下是配置过程: 步骤一:创建vue.config.js文件 在项目根目录下创建vue.conf…

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