java使用注解优雅地实现参数校验

你是否一直被入参的校验困扰,写着ifelseifelse的垃圾代码。你是否也幻想只要使用一行代码就完事,就像这样:

@RegexAnnotation(regexEnum = RegexEnum.IDENTITY, message = "身份证校验失败")

private String identity;

为了程序员的尊严,让我们学习一下这个小技能吧。

先介绍下需要引入的功能包:javax.validation.constraints

<dependency>

    <groupId>javax.validation</groupId>

    <artifactId>validation-api</artifactId>

    <version>1.1.0.Final</version>

</dependency>

通过继承前人的注解,我们可以省略很多工作。让我们开始吧~

自定义注解:

@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})

@Retention(RetentionPolicy.RUNTIME)

@Documented

@Constraint(validatedBy = {RegexValidator.class}) // 关联RegexValidator类

public @interface RegexAnnotation {

    RegexEnum regexEnum();

    String message() default "校验失败";

    Class<?>[] groups() default {}; // 约束注解在验证时所属的组别

    Class<? extends Payload>[] payload() default {}; // 约束注解的有效负载

}

关联注解的具体逻辑校验类:

public class RegexValidator implements ConstraintValidator<RegexAnnotation, Object> {

    RegexEnum regexEnum;

    @Override

    public void initialize(RegexAnnotation constraintAnnotation) {

        regexEnum = constraintAnnotation.regexEnum();

    }

    @Override

    public boolean isValid(Object value, ConstraintValidatorContext context) {

        if(value==null){

            return false;

        }

        Pattern pattern = Pattern.compile(regexEnum.getRegex());

        return pattern.matcher(value.toString()).matches();

    }

}

使用注解校验的请求类:

@Data

public class ConstraintRequest {

    @NotNull(message = "id不能为空")

    private String id;

    @Max(value = 10, message = "name最大长度为10")

    private String name;

    @NotNull(message = "firstName不能为空")

    @Size(min = 5, max = 9, message = "firstName长度须在5-10之间")

    private String firstName;

    @Pattern(regexp = "^[a-zA-Z0-9_.-]+@.*\\.[a-zA-Z0-9]{2,6}$", message = "邮箱格式错误")

    private String email;

    @AssertTrue(message = "flag字段须为true")

    private boolean flag;

    @Future(message = "时间须超过当前时间")

    private Date date;

    @RegexAnnotation(regexEnum = RegexEnum.IDENTITY, message = "身份证校验失败")

    private String identity;

}

单测验证:

public class RegexAnnotationTest {

    @Test

    public void testRegex(){

        ConstraintRequest request = new ConstraintRequest();

        request.setName("1234567890a");

        request.setDate(new Date());

        request.setEmail("test");

        request.setIdentity("310");

        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();

        Validator validator = factory.getValidator();

        Set<ConstraintViolation<ConstraintRequest>> violationSet = validator.validate(request);

        for (ConstraintViolation<ConstraintRequest> violation : violationSet) {

            System.out.println(violation.getMessage());

        }

    }

}

测试输出:

INFO: HV000001: Hibernate Validator 5.2.4.Final

id不能为空

flag字段须为true

name最大长度为10

身份证校验失败

firstName不能为空

邮箱格式错误

时间须超过当前时间


学完,收工。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容