Springboot 自定义验证注解及提示消息模板

本文介绍了如何在Spring Boot项目中使用自定义注解`InspectFilePath`进行文件名和路径的合法性检查,包括Lombok和Hutool工具的整合,并展示了如何配置验证器和在请求方法及实体类中应用验证。

依赖

plugins {
    id 'org.springframework.boot' version '2.5.3'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
	id 'java'
}

group = 'com.stone'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.11'

repositories {
    mavenLocal()
    maven {
        url 'https://maven.aliyun.com/repository/public/'
    }
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web:2.5.3'

    // Lombok
    compileOnly 'org.projectlombok:lombok:1.18.20'
    annotationProcessor 'org.projectlombok:lombok:1.18.20'

    // Hutool 工具包
    implementation 'cn.hutool:hutool-all:5.7.7'

    // 参数验证
    implementation 'org.springframework.boot:spring-boot-starter-validation:2.5.3'

	testImplementation('org.springframework.boot:spring-boot-starter-test:2.5.3') {
		exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
	}
}

自定义验证注解 InspectFilePath.java

import com.stone.common.config.validator.InspectFilePathValidator;

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

/**
 * @author <a href="https://github.com/zichen1019">zichen</a>
 */
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = InspectFilePathValidator.class)
public @interface InspectFilePath {

    String message() default "文件{param}禁止包含特殊符号:{toast}";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

    boolean isFileName() default false;

}

自定义注解实现类 InspectFilePathValidator.java

import cn.hutool.core.util.StrUtil;
import com.stone.common.config.annotations.InspectFilePath;
import com.stone.common.utils.common.PreventFilePathAttacks;
import org.hibernate.validator.constraintvalidation.HibernateConstraintValidator;
import org.hibernate.validator.constraintvalidation.HibernateConstraintValidatorContext;
import org.hibernate.validator.constraintvalidation.HibernateConstraintValidatorInitializationContext;

import javax.validation.ConstraintValidatorContext;
import javax.validation.metadata.ConstraintDescriptor;

/**
 * @author <a href="https://github.com/zichen1019">zichen</a>
 */
public class InspectFilePathValidator implements HibernateConstraintValidator<InspectFilePath, CharSequence> {

    private boolean isFileName;

    @Override
    public void initialize(ConstraintDescriptor<InspectFilePath> constraintDescriptor, HibernateConstraintValidatorInitializationContext initializationContext) {
        isFileName = constraintDescriptor.getAnnotation().isFileName();
    }

    /**
     * 检查是否符合规则
     *
     * @param value 被检查的值
     * @param constraintValidatorContext    验证上下文
     * @return  true 符合规则 false 不符合规则
     */
    @Override
    public boolean isValid(CharSequence value, ConstraintValidatorContext constraintValidatorContext) {
        String toast;
        if (isFileName) {
            toast = PreventFilePathAttacks.inspectFileName(value.toString());
            if (StrUtil.isNotBlank(toast)) {
                constraintValidatorContext.unwrap( HibernateConstraintValidatorContext.class ).addMessageParameter( "file", "名称" ).addMessageParameter( "toast", toast );
                return false;
            }
        }
        toast = PreventFilePathAttacks.inspectFilePath(value.toString());
        if (StrUtil.isNotBlank(toast)) {
            constraintValidatorContext.unwrap( HibernateConstraintValidatorContext.class ).addMessageParameter( "file", "路径" ).addMessageParameter( "toast", toast );
            return false;
        }
        return true;
    }

}

注入校验对象

import org.hibernate.validator.HibernateValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.validation.Validation;
import javax.validation.Validator;

/**
 * 默认会校验完所有属性,然后将错误信息一起返回,但很多时候不需要这样,一个校验失败了,其它就不必校验了.
 *
 * @author zichen
 */
@Configuration
public class ValidatorConfig {

    @Bean
    public Validator validator() {
        return Validation.byProvider(HibernateValidator.class)
                .configure()
                .failFast(true)
                .buildValidatorFactory()
                .getValidator();
    }

}

请求方法上添加验证注解@Validated

    @GetMapping("/xxx")
    public void xxx(@Validated XxxDTO xxxDTO) {
    }

实体类增加验证

import com.stone.common.config.annotations.InspectFilePath;
import lombok.Data;

/**
 * @author <a href="https://github.com/zichen1019">zichen</a>
 */
@Data
public class YsjlDeleteEnclosureImgDTO {

    @InspectFilePath(isFileName = true)
    private String fileName;

    private String id;

}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值