栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JSR303参数校验

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JSR303参数校验

1.给Bean添加校验注解:javax.validation.constraints,并定义自己的message提示

例如:

    @NotNull(message = "修改必须指定ID", groups = {UpdateGroup.class})
	@Null(message = "新增不能指定ID", groups = {AddGroup.class})
	@TableId
	private Long brandId;

    @NotBlank(message = "名称不能为空", groups = {AddGroup.class, UpdateGroup.class})
	private String name;

    @Pattern(regexp = "^[a-zA-Z]$", message = "检索首字母必须是一个字母")
    private String firstLetter;

NotNull和Null是校验类下规则,message指定校验失败时的报错信息。groups是指定分组(UpdateGroup和AddGroup是自定义的接口类),需要配合参数注解指定分组来确定是否需要校验。

2.开启校验功能,可以使用java规范(javax.validation.Valid)@Valid,但是该注解没有任何属性。我们可以使用Spring自带的(org.springframework.validation.annotation.Validated)@Validated可以支持分组功能。

@RequestMapping("/update")
public RespData update(@Validated({UpdateGroup.class}) @RequestBody BrandEntity brand)

UpdateGroup.class指定这是更新操作,只有上面1中属于UpdateGroup分组的字段才需要校验,

@RequestBody 自动将传递的json参数映射为BrandEntity实体对象。

注意:默认没有指定分组的校验注解,在分组校验情况下不生效,只会在@Validated生效;

3.获取校验结果:

        方式一通过参数后紧跟BindingResult对象:        

public RespData save(@Validated({AddGroup.class}) @RequestBody BrandEntity brand, BindingResult result){
	if(result.hasErrors()){
	    Map map = new HashMap<>();
	    //获取校验的错误结果
	    result.getFieldErrors().forEach((item) -> {
	        //FieldError获取错误提示
	        String message = item.getDefaultMessage();
	        //获取错误的属性的名字
	        String field = item.getField();
	        map.put(field, message);
	    });
	    return RespData.error(400, "提交的数据不合法").put("data", map);
	}
}

方式二统一处理异常,自定义异常处理类:

@Slf4j
//@ResponseBody
//@ControllerAdvice(basePackages = "com.example.controller")
@RestControllerAdvice(basePackages = "com.example.controller")
public class ExampleExceptionControllerAdvice {

    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public RespData handleValidException(MethodArgumentNotValidException e){
        log.error("数据校验出现问题{},异常类型{}", e.getMessage(), e.getClass());
        BindingResult bindingResult = e.getBindingResult();
        Map errorMap = new HashMap<>();
        bindingResult.getFieldErrors().forEach((fieldError) -> {
            errorMap.put(fieldError.getField(), fieldError.getDefaultMessage());
        });
        return RespData.error(BizCodeEnume.VALID_EXCEPTION.getCode(), BizCodeEnume.VALID_EXCEPTION.getMsg()).put("data", errorMap);
    }

    @ExceptionHandler(value = Throwable.class)
    public RespData handleException(Throwable throwable){
        return RespData.error(BizCodeEnume.UNKNOW_EXCEPTION.getCode(), BizCodeEnume.UNKNOW_EXCEPTION.getMsg());
    }
}

错误类型枚举类:

public enum BizCodeEnume {

    UNKNOW_EXCEPTION(10000, "系统未知异常"),
    VALID_EXCEPTION(10001, "参数格式校验失败");

    private int code;
    private String msg;

    BizCodeEnume(int code, String msg){
        this.code = code;
        this.msg = msg;
    }

    public int getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }
}

@RestControllerAdvice是@ResponseBody和@ControllerAdvice的合并效果,

basePackages指定处理该包下的异常。

@ExceptionHandler指定处理的异常

以上即可实现基本的数据校验功能,但有时候需要我们自定义校验方法,创建自定义校验器

例如我们要实现一个字段只能是指定值中的一个:

@ListValue(vals= {0, 1}, message = "必须是指定的值")
private Integer status;

首先需要导入依赖:


   jakarta.validation
   jakarta.validation-api
   2.0.2
   compile

然后我们可以参考@NotBlank编写:

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

@Documented
@Constraint(validatedBy = {ListValueConstraintValidator.class})
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ListValue {

    String message() default "{com.example.valid.ListValue.message}";

    Class[] groups() default {};

    Class[] payload() default {};

    int[] vals() default {};
}

message对应错误消息,可以在resources文件夹下创建ValidationMessages.properties文件,在文件中编写对应的错误消息:

com.example.valid.ListValue.message=必须是指定的值

也可以在写注解时指定message。

@Constraint(validatedBy = {ListValueConstraintValidator.class})确定注解的校验器:

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.HashSet;
import java.util.Set;

public class ListValueConstraintValidator implements ConstraintValidator {

    private Set set = new HashSet<>();
    //初始化方法
    @Override
    public void initialize(ListValue constraintAnnotation) {
        int[] vals = constraintAnnotation.vals();
        for (int val : vals){
            set.add(val);
        }
    }

    
    @Override
    public boolean isValid(Integer value, ConstraintValidatorContext constraintValidatorContext) {
        return set.contains(value);
    }
}

至此完成了ListValue的自定义校验功能。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/895084.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号