首页 热点 业界 科技快讯 数码 电子消费 通信 前沿动态 电商

今日热闻!SpringBoot利用validation实现优雅的校验参数

2022-06-15 06:02:10 来源 : 软件开发网

目录

1、前言

2、常用校验

3、spring boot的数据自动校验功能

3.1 引入依赖

3.2 构建启动类

3.3 创建需要被校验的实体类

3.4 在Controller中校验数据

3.5 统一异常处理

4、自定义校验注解

4.1 @NameValidation

4.2 校验类NameValidationValidator

4.3 在Person类增加新注解

5、总结

1、前言

数据的校验是交互式网站一个不可或缺的功能,前端的js校验可以涵盖大部分的校验职责,如用户名唯一性,生日格式,邮箱格式校验等等常用的校验。但是为了避免用户绕过浏览器,使用http工具直接向后端请求一些违法数据,服务端的数据校验也是必要的,可以防止脏数据落到数据库中,如果数据库中出现一个非法的邮箱格式,也会让运维人员头疼不已。可以使用本文将要介绍的validation来对数据进行校验。

2、常用校验

1.JSR303/JSR-349: JSR303是一项标准,只提供规范不提供实现,规定一些校验规范即校验注解,如@Null,@NotNull,@Pattern,位于javax.validation.constraints包下。JSR-349是其的升级版本,添加了一些新特性。

@Null 被注释的元素必须为null

@NotNull 被注释的元素必须不为null

@AssertTrue 被注释的元素必须为true

@AssertFalse 被注释的元素必须为false

@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值

@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值

@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值

@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值

@Size(max, min) 被注释的元素的大小必须在指定的范围内

@Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内

@Past 被注释的元素必须是一个过去的日期

@Future 被注释的元素必须是一个将来的日期

@Pattern(value) 被注释的元素必须符合指定的正则表达式

2.hibernate validation:hibernate validation是对这个规范的实现,并增加了一些其他校验注解,如@Email,@Length,@Range等等

@Email 被注释的元素必须是电子邮箱地址

@Length 被注释的字符串的大小必须在指定的范围内

@NotEmpty 被注释的字符串的必须非空

@Range 被注释的元素必须在合适的范围内

3.spring validation:spring validation对hibernate validation进行了二次封装,在springmvc模块中添加了自动校验,并将校验信息封装进了特定的类中

3、spring boot的数据自动校验功能3.1 引入依赖

spring-web模块使用了hibernate-validation,并且databind模块也提供了相应的数据绑定功能。

org.springframework.boot spring-boot-starter-web

我们只需要引入spring-boot-starter-web依赖即可,如果查看其子依赖,可以发现如下的依赖:

org.hibernate hibernate-validator com.fasterxml.jackson.core jackson-databind3.2 构建启动类@SpringBootApplicationpublic class App { public static void main(String[] args) { SpringApplication.run(App.class, args); System.out.println("Start app success."); }}3.3 创建需要被校验的实体类public class Person { @NotEmpty(message = "name不能为空") private String name; @Range(min = 0, max = 100, message = "age不能大于100小于0") private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; }}3.4 在Controller中校验数据

springmvc为我们提供了自动封装表单参数的功能,一个添加了参数校验的典型controller如下所示。

@RequestMapping("/test")public String valid(@Validated Person person, BindingResult bindingResult) { if (bindingResult.hasErrors()) { for (FieldError fieldError : bindingResult.getFieldErrors()) { System.out.println(fieldError); } return "fail"; } return "success";}

值得注意的地方:

参数Persison前需要加上@Validated注解,表明需要spring对其进行校验,而校验的信息会存放到其后的BindingResult中。注意,必须相邻,如果有多个参数需要校验,形式可以如下。valid(@Validated Person person, BindingResult personBindingResult ,@Validated Person2 person2, BindingResult person2BindingResult);即一个校验类对应一个校验结果。

校验结果会被自动填充,在controller中可以根据业务逻辑来决定具体的操作,如跳转到错误页面。

一个最基本的校验就完成了.

启动容器测试结果如下:

Field error in object "person" on field "age": rejected value [105]; codes [Range.person.age,Range.age,Range.int,Range]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [person.age,age]; arguments []; default message [age],100,0]; default message [age不能大于100小于0]

3.5 统一异常处理

前面那种方式处理校验错误,略显复杂,而且一般网站都会对请求错误做统一的404页面封装,如果数据校验不通过,则Spring boot会抛出BindException异常,我们可以捕获这个异常并使用Result封装返回结果。通过@RestControllerAdvice定义异常捕获类。

Controller类:

@RequestMapping(value = "valid", method = RequestMethod.GET)public String valid(@Validated Person person) { System.out.println(person); return "success";}

统一异常处理类:

@RestControllerAdvicepublic class BindExceptionHanlder { @ExceptionHandler(BindException.class) public String handleBindException(HttpServletRequest request, BindException exception) { List allErrors = exception.getFieldErrors(); StringBuilder sb = new StringBuilder(); for (FieldError errorMessage : allErrors) { sb.append(errorMessage.getField()).append(": ").append(errorMessage.getDefaultMessage()).append(", "); } System.out.println(sb.toString()); return sb.toString(); }}

测试: http://localhost:8080/valid?age=105&name=steven

输出:age: age不能大于100小于0,

4、自定义校验注解4.1 @NameValidation@Documented@Constraint(validatedBy = NameValidationValidator.class)@Target({ElementType.METHOD, ElementType.FIELD})@Retention(RUNTIME)public @interface NameValidation { String message() default "不是合法的名字"; Class[] groups() default {}; Class[] payload() default {}; @Target({PARAMETER, ANNOTATION_TYPE}) @Retention(RUNTIME) @Documented @interface List { NameValidation[] value(); }}4.2 校验类NameValidationValidatorpublic class NameValidationValidator implements ConstraintValidator { @Override public boolean isValid(String value, ConstraintValidatorContext context) { if ("steven".equalsIgnoreCase(value)) { return true; } String defaultConstraintMessageTemplate = context.getDefaultConstraintMessageTemplate(); System.out.println("default message :" + defaultConstraintMessageTemplate); //禁用默认提示信息//context.disableDefaultConstraintViolation(); //设置提示语//context.buildConstraintViolationWithTemplate("can not contains blank").addConstraintViolation(); return false; }}4.3 在Person类增加新注解@NotEmpty(message = "name不能为空")@NameValidationprivate String name;

测试: http://localhost:8080/valid?age=105&name=lxy

输出:age: age不能大于100小于0, name: 不是合法的名字,

5、总结

通过上面的例子可以看出,其实使用很简单,但是有没有注意到一个问题,错误信息没有实现国际化。hibernate-validator国际化还是比较繁琐的,包含:


(资料图片)

SpringBoot场景国际化

SpringMvc场景国际化

Spring Jersey场景国际化

非Spring场景国际化

以上就是SpringBoot利用validation实现优雅的校验参数的详细内容,更多关于SpringBoot validation校验参数的资料请关注软件开发网其它相关文章!

标签: 的范围内 异常处理 数据自动

相关文章

最近更新
观焦点:超萌相机 2023-03-01 12:29:37
海南百货网 2023-03-01 12:13:44
焦点热讯:宜点充 2023-02-28 10:10:16
天天关注:小铺CEO 2023-02-28 10:07:13
【世界聚看点】KaFit 2023-02-28 09:31:37
葱天下 2023-02-28 09:17:03
渔界竞钓 2023-02-28 08:15:29
焦点快看:鲸奇视频 2023-02-28 06:30:37
环球热议:萝小逗 2023-02-27 23:25:49
简讯:小码公交 2023-02-27 23:16:12
彼岸花 2023-02-27 22:32:52
时时夺宝 2023-02-27 21:37:50
天天动态:袜之源 2023-02-27 21:29:50
天天资讯:AI空气 2023-02-27 20:19:46
世界时讯:绘读 2023-02-27 20:19:41
看点:一元得购 2023-02-27 19:26:28