@Validated注解使用

@Validated注解使用@ValidatedpublicStringsyncTable(@ValidatedSyncByTableRequestrequest){logger.debug("request_info:"+JsonUtil.toJson(request));Stringresponse=Response.success(syncService….

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全家桶1年46,售后保障稳定

Spring-Boot-Validation

什么是Validation

在我们的RESTful Service中帮助我们完成期望的数据校验,通过配置Validation可以很轻松的完成对数据的约束
在我们接收到不想要的数据时:

  • 返回错误的状态码和错误的提示信息
  • 在响应的结果中去除敏感信息
  • …

错误的状态码

返回的响应码推荐使用400->bad request.

引导使用正确的REST资源

通过提供的报错信息来引导合理使用restful服务的资源,并且完成CRUD方法的调用.

通过Validation我们可以使用一种相同的模板方法来完成异常控制

在SpringBoot中使用Validation

错误的相应类型

如果你是用的是application/xml的处理类型,SpringBoot将默认返回状态码为415的Media Type.

无效的JSON内容

如果你发送了一个无效的JSON内容,你会的到状态码为400的Bad Request.

数据缺失的JSON

如果你的请求JSON中缺失数据,springboot将返回201状态码给你.

自定义Validation

接下来将使用Hibernate自带的Validatior来自定义一套Bean的Validator API.

在SpringBoot的项目中使用Hibernate的Validator是非常容易的

在Bean上通过Validations 注解实现

使用@Size注解来指定数据的长度和报错是提示的内容

@Entity
public class Student { 
   
  @Id
  @GeneratedValue
  private Long id;
  
  @NotNull
  @Size(min=2, message="Name should have atleast 2 characters")
  private String name;
  
  @NotNull
  @Size(min=7, message="Passport should have atleast 2 characters")
  private String passportNumber;

Jetbrains全家桶1年46,售后保障稳定

这里将可以使用到的注解放在下面一遍查看也可以看我的另一篇博客

空检查

@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=) Checks whether the annotated value lies between (inclusive) the specified minimum and maximum.

@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=)

在请求的时候进行Valid配置

post请求对于post在使用@Valid的时候需要在注解后跟随@RequestBoday,如果使用url传参,使用@Valid的时候也需要使用@RequestParam

public ResponseEntity<Object> createStudent(@Valid @RequestBody Student student) { 
   

get请求同理,直接使用@Valid+@RequestParam就可以了
这是对接口发出请求,我们可以看到服务返回了404的Bad Request

@GetMapping("/type/{type}/{year}")
	public Object selectRootByType(@NotNull(message = "结构层级不能为空!") @PathVariable("type") ExamTypeEnum type,
			@NotNull(message = "年份不能为空!") @PathVariable("year") Integer year) 
  {
    "name": "",
    "passportNumber": "A12345678"
  }

但是并没有返回给我们相关的提示信息.

  • 消费者知道这是一个Bad Request
  • 但是他们不知道为什么错了?那个元素出错了?为了解决这个错误该如何解决呢?

自定义Validation Response

首先需要创建一个简单的错误相应Bean

public class ErrorDetails { 
   
  private Date timestamp;
  private String message;
  private String details;

  public ErrorDetails(Date timestamp, String message, String details) { 
   
    super();
    this.timestamp = timestamp;
    this.message = message;
    this.details = details;
  }
通过继承ResponseEntityExceptionHandler来自定义异常处理类,需要在类上添加注解@ControllerAdvice
@ControllerAdvice
@RestController
public class CustomizedResponseEntityExceptionHandler extends ResponseEntityExceptionHandler { 
   
通过ErrorDetails来封装错误信息并且将错误信息通过json的形式返回给前段进行展示
@ControllerAdvice
@RestController
public class CustomizedResponseEntityExceptionHandler extends ResponseEntityExceptionHandler { 
   
  @ExceptionHandler(StudentNotFoundException)
  public final ResponseEntity<ErrorDetails> handleUserNotFoundException(StudentNotFoundException ex, WebRequest request) { 
   
    ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(),
        request.getDescription(false));
    return new ResponseEntity<>(errorDetails, HttpStatus.NOT_FOUND);
  }
如果请求的时候提供一个错误的参数,你讲收到后台发来的提示
{
    "name": "",
    "passportNumber": "A12345678"
  }

响应结果

{
    "timestamp": "2018-12-13T14:02:24.066+0000",
    "message": "Validation Failed",
    "details": "org.springframework.validation.BeanPropertyBindingResult: 1 errors\nField error in object 'student' on field 'name': rejected value []; codes [Size.student.name,Size.name,Size.java.lang.String,Size]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [student.name,name]; arguments []; default message [name],2147483647,2]; default message [用户名长度不能小于2]"
}

自定义Validators

JSR 303验证提供可很多默认的验证模式,但是有的时候我们还是需要根据自己的需求自定义验证器

javax 提供了一个validation包用来帮助我们完成参数校验

如果想要实现自己的Validator就必须要实现ConstraintValidator,实现这个类可以帮助我们在解析参数时通过@Valid标注的方法参数进行验证

public class InRangeValidator implements ConstraintValidator<InRange, Integer> { 
   

    private int min;
    private int max;

    /** * 用来完成将注解中的内容初始化 */
    @Override
    public void initialize(InRange constraintAnnotation) { 
   
        this.min = constraintAnnotation.min();
        this.max = constraintAnnotation.max();
    }

    @Override
    public boolean isValid(Integer value, ConstraintValidatorContext context) { 
   
        return value == null || (value >= min && value <= max);
    }
}

实现自己的注解也是很容易,只需要添加Constraint注解来实现对注解的约束,同时定义默认值和默认的错误消息

@Target({ 
   ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = { 
    InRangeValidator.class })
public @interface InRange { 
   
    String message() default "Value is out of range";
 
    Class<?>[] groups() default { 
   };
 
    Class<? extends Payload>[] payload() default { 
   };
 
    int min() default Integer.MIN_VALUE;
 
    int max() default Integer.MAX_VALUE;
}

高级使用

@Validator一系列注解不仅仅给我们提供了默认的信息提示以及相应的参数比较.同时还在注解中定义了groups的概念,通过引入自定义interface可以创建一些显示的声明从而帮助我们完成更好的验证

设置分组

在注解参数Group中添加interface的方法名来区分组别

  @PostMapping
    public Object insert(@RequestBody @Validated(value = { 
   ValidateGroups.ValidateSave.class}) PositionInfoDto.Save save) { 
   
        return testService.insert(save);
    }
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/216556.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • c语言函数回调详解_c语言回调函数例子

    c语言函数回调详解_c语言回调函数例子关于静态库和动态库的使用和制作方法。http://blog.csdn.net/morixinguan/article/details/52451612今天我们要搞明白的一个概念叫回调函数。什么是回调函数?百度的权威解释如下:回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实…

    2022年10月30日
  • 汇编介绍

    汇编介绍汇编大多是指汇编语言,汇编程序。把汇编语言翻译成机器语言的过程称为汇编。在汇编语言中,用助记符(Memoni)代替操作码,用地址符号(Symbol)或标号(Label)代替地址码。这样用符号代替机器语言的二进制码,就把机器语言变成了汇编语言。于是汇编语言亦称为符号语言。用汇编语言编写的程序,机器不能直接识别,要由一种程序将汇编语言翻译成机器语言,这种起翻译作用的程序叫汇编程序…

    2022年10月13日
  • 百度快照更新周期、百度收录更新时间[通俗易懂]

    百度快照更新周期、百度收录更新时间[通俗易懂]很多做SEO的都不清楚百度快照的更新周期,所以很多时候都不能有针对性的对网站进行操作,错过了很多机会。百度收录的更新日期一般是每个月的11号和26号,特别是26号,更新最大,但K站也是最多的。另外百度也有一个小的更新的日期,即每周四凌晨4点左右,对网站的访问量没有什么效果,只有到了中午的日期,百度对网站关键字的搜索停止重新调整之后,才会有访问量上的大的变化,有升有降。总体上来说是大致为一个

    2022年9月27日
  • 综合应用WPF/WCF/WF/LINQ之二十八:代码生成器之DBMLToInfo

    综合应用WPF/WCF/WF/LINQ之二十八:代码生成器之DBMLToInfo

    2021年7月25日
  • Java中数字的四舍五入和取整

    Java中数字的四舍五入和取整Java中对数字进行四舍五入或取整处理经常使用Math库中的三个方法:ceilfloorround1ceil向上取整ceil英文释义:天花板。天花板在上面,所以是向上取整,好记了。Math.ceil函数接收一个double类型的参数,用于对数字进行向上取整(遇小数进1),即返回一个大于或等于传入参数的最小整数(但还是以double类型返回)。2floor向下取整floor英文释义:地板。地板在下面,所以是向下取整,好记了。Math.floor函数接收一个double

    2022年7月7日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号