@Validated和@Valid校验参数

@Validated和@Valid校验参数

参考:

@Validated和@Valid校验参数、级联属性、List

java valid payload_Spring Validation最佳实践及其实现原理,参数校验没那么简单!

@Validated和@Valid的区别

在Controller中校验方法参数时,使用@Valid和@Validated并无特殊差异(若不需要分组校验的话):
@Valid:标准JSR-303规范的标记型注解,用来标记验证属性和方法返回值,进行级联和递归校验
@Validated:Spring的注解,是标准JSR-303的一个变种(补充),提供了一个分组功能,可以在入参验证时,根据不同的分组采用不同的验证机制

方法级别:

@Valid可以用在属性级别约束,用来表示级联校验

@Valid可用于方法、字段、构造器和参数上

@Valid只能校验JavaBean,而List不是JavaBean所以校验会失败

@Validated注解可以用于类级别,用于支持Spring进行方法级别的参数校验。提供了一个分组功能,不需要级联递归时,个人建议使用 @Validated校验

@Validated只能用在类、方法和参数上,不能用于字段属性上

内置的验证约束注解 :

空检查
 @Null       验证对象是否为null
 @NotNull    验证对象是否不为null, 无法查检长度为0的字符串
 @NotBlank 检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格.
 @NotEmpty 检查约束元素是否为NULL或者是EMPTY.

Booelan检查
 @AssertTrue     验证 Boolean 对象是否为 true
 @AssertFalse    验证 Boolean 对象是否为 false

长度检查
 @Size(min=, max=) 验证对象(Array,Collection,Map,String)长度是否在给定的范围之内
 @Length(min=, max=) Validates that the annotated string is between min and max included.

日期检查
 @Past           验证 Date 和 Calendar 对象是否在当前时间之前
 @Future     验证 Date 和 Calendar 对象是否在当前时间之后
 @Pattern    验证 String 对象是否符合正则表达式的规则

数值检查,建议使用在Stirng,Integer类型,不建议使用在int类型上,因为表单值为“”时无法转换为int,但可以转换为Stirng为"",Integer为null
 @Min            验证 Number 和 String 对象是否大等于指定的值
 @Max            验证 Number 和 String 对象是否小等于指定的值
 @DecimalMax 被标注的值必须不大于约束中指定的最大值. 这个约束的参数是一个通过BigDecimal定义的最大值的字符串表示.小数存在精度
 @DecimalMin 被标注的值必须不小于约束中指定的最小值. 这个约束的参数是一个通过BigDecimal定义的最小值的字符串表示.小数存在精度
 @Digits     验证 Number 和 String 的构成是否合法
 @Digits(integer=,fraction=) 验证字符串是否是符合指定格式的数字,interger指定整数精度,fraction指定小数精度。

@Range(min=, max=) 检查数字是否介于min和max之间.
 @Range(min=10000,max=50000,message="range.bean.wage")
 private BigDecimal wage;

@Valid 递归的对关联对象进行校验, 如果关联对象是个集合或者数组,那么对其中的元素进行递归校验,如果是一个map,则对其中的值部分进行校验.(是否进行递归验证)
 @CreditCardNumber信用卡验证
 @Email  验证是否是邮件地址,如果为null,不进行验证,算通过验证。
 @ScriptAssert(lang= ,script=, alias=)
 @URL(protocol=,host=, port=,regexp=, flags=)
限制 说明
 @Null   限制只能为null
 @NotNull    限制必须不为null
 @AssertFalse    限制必须为false
 @AssertTrue 限制必须为true
 @DecimalMax(value)  限制必须为一个不大于指定值的数字
 @DecimalMin(value)  限制必须为一个不小于指定值的数字
 @Digits(integer,fraction)   限制必须为一个小数,且整数部分的位数不能超过integer,小数部分的位数不能超过fraction
 @Future 限制必须是一个将来的日期
 @Max(value) 限制必须为一个不大于指定值的数字
 @Min(value) 限制必须为一个不小于指定值的数字
 @Past   限制必须是一个过去的日期
 @Pattern(value) 限制必须符合指定的正则表达式
 @Size(max,min)  限制字符长度必须在min到max之间
 @Past   验证注解的元素值(日期类型)比当前时间早
 @NotEmpty   验证注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0)
 @NotBlank   验证注解的元素值不为空(不为null、去除首位空格后长度为0),不同于@NotEmpty,@NotBlank只应用于字符串且在比较时会去除字符串的空格
 @Email  验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式

校验参数、级联属性

1、校验参数
当入参为实体对象时,需要在方法上加@Valid或@Validated或者在参数前加@Valid或@Validated,或者在类上加@Validated

@Valid
@GetMapping(“/exam-info”)
public Boolean getInfo(User user){…}

@GetMapping(“/exam-info”)
public Boolean getInfo(@Valid User user){…}

@Validated
@GetMapping(“/exam-info”)
public Boolean getInfo(User user){…}

@GetMapping(“/exam-info”)
public Boolean getInfo(@Validated User user){…}

public Class User{
@NotNull(“id不能为空”)
private Integer id;
}

2、嵌套验证
@valid作用于属性上有嵌套验证作用,@validated不能作用于属性上,如下代码在User类的属性car上添加@valid注解,当传参id为空时会报错。

@GetMapping(“/exam-info”)
public Boolean getInfo(@Valid User user){…}

public class User{
@Valid
@NotNull(“car不能为空”)
private Car car;
}
public class Car{
@NotNull(“id不能为空”)
private Integer id;
}

校验List

@Valid只能校验JavaBean,而List不是JavaBean所以校验会失败,介绍三种解决办法

实战使用:

创建自定义的校验
ListValue
package com.showlin.common.valid;

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

@Documented
@Constraint(validatedBy = { ListValueConstraintValidator.class })
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
public @interface ListValue {
    String message() default "{com.showlin.common.valid.ListValue.message}";

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

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

    int[] vals() default { };
}

ListValueConstraintValidator
package com.showlin.common.valid;

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

public class ListValueConstraintValidator implements ConstraintValidator<ListValue,Integer> {

    private Set<Integer> set = new HashSet<>();
    //初始化方法
    @Override
    public void initialize(ListValue constraintAnnotation) {

        int[] vals = constraintAnnotation.vals();
        for (int val : vals) {
            set.add(val);
        }

    }

    //判断是否校验成功

    /**
     *
     * @param value 需要校验的值
     * @param context
     * @return
     */
    @Override
    public boolean isValid(Integer value, ConstraintValidatorContext context) {

        return set.contains(value);
    }
}
ValidationMessages.properties
com.showlin.common.valid.ListValue.message=Ö»ÄÜÊäÈë0»ò1
AddGroup
public interface AddGroup {
}
UpdateStatusGroup
public interface UpdateStatusGroup {
}
使用@ListValue
	/**
	 * 显示状态[0-不显示;1-显示]
	 */
	//	@Pattern()
	@NotNull(groups = {AddGroup.class, UpdateStatusGroup.class})
	@ListValue(vals={0,1},groups = {AddGroup.class, UpdateStatusGroup.class})
	private Integer showStatus;
RRExceptionHandler
/**
 * Copyright 2018 人人开源 http://www.renren.io
 * 

* Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at *

* http://www.apache.org/licenses/LICENSE-2.0 *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package com.yymt.common.exception; import com.yymt.common.utils.R; import org.apache.shiro.authz.AuthorizationException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.dao.DuplicateKeyException; import org.springframework.validation.FieldError; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.ServletRequestBindingException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.multipart.MultipartException; import javax.validation.ConstraintViolationException; /** * 异常处理器 * * @author chenshun * @email [email protected] * @date 2016年10月27日 下午10:16:19 */ @RestControllerAdvice public class RRExceptionHandler { private Logger logger = LoggerFactory.getLogger(getClass()); /** * 处理自定义异常 */ @ExceptionHandler(RRException.class) public R handleRRException(RRException e) { R r = new R(); r.put("code", e.getCode()); r.put("msg", e.getMessage()); return r; } @ExceptionHandler(DuplicateKeyException.class) public R handleDuplicateKeyException(DuplicateKeyException e) { logger.error(e.getMessage(), e); return R.error(ResultEnum.DATA_ALREADY_EXIST); } @ExceptionHandler(AuthorizationException.class) public R handleAuthorizationException(AuthorizationException e) { logger.error(e.getMessage(), e); return R.error(ResultEnum.NO_PERMISSION); } @ExceptionHandler(MultipartException.class) public R handleMultipartException(MultipartException e) { logger.error(e.getMessage(), e); return R.error(ResultEnum.UPLOAD_ERROR); } @ExceptionHandler(MethodArgumentNotValidException.class) public R handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { logger.error(e.getMessage(), e); FieldError fieldError = e.getBindingResult().getFieldError(); return R.error(fieldError.getField() + fieldError.getDefaultMessage()); } @ExceptionHandler({ServletRequestBindingException.class}) public R handleServletRequestBindingException(ServletRequestBindingException ex) { return R.error(ex.getMessage()); } @ExceptionHandler({ConstraintViolationException.class}) public R handleConstraintViolationException(ConstraintViolationException ex) { return R.error(ex.getConstraintViolations().stream().findFirst().get().getMessage()); } @ExceptionHandler(Exception.class) public R handleException(Exception e) { logger.error(e.getMessage(), e); return R.error(); } }

你可能感兴趣的:(代码片段,spring,java,面试)