在进行项目开发的过程中,我们会对外提供接口,一般会对接口的入参进行判空等校验,如果每个接口写
if (param == null)
这种代码,难免有些冗余,springboot帮我们整合了validator ,我们可以直接使用,减少重复的工作。
- 引入依赖
首先引入依赖,springboot也整合了Hibernate Validator,我们可以更方便的使用
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
- 给请求实体类加上需要注解
@NotBlank
相当于判断字符串不为空且不为空串
@NotNull
相当于判断对象不为空
![]()
相类似的注解还有很多:
释义 | |
---|---|
@Null | 必须为null |
@NotNull | 不能为null |
@AssertTrue | 必须为true |
@AssertFalse | 必须为false |
@Min | 必须为数字,其值大于或等于指定的最小值 |
@Max | 必须为数字,其值小于或等于指定的最大值 |
@DecimalMin | 必须为数字,其值大于或等于指定的最小值 |
@DecimalMax | 必须为数字,其值小于或等于指定的最大值 |
@Size | 集合的长度 |
@Digits | 必须为数字,其值必须再可接受的范围内 |
@Past | 必须是过去的日期 |
@Future | 必须是将来的日期 |
@Pattern | 必须符合正则表达式 |
必须是邮箱格式 | |
@Length | 长度范围 |
@NotEmpty | 不能为null,长度大于0 |
@Range | 元素的大小范围 |
@NotBlank | 不能为null,字符串长度大于0(限字符串) |
- 给controller加上
@Validated
注解
给api的入口加上
@Validated
注解,并且通过绑定BindingResult
获取错误信息![]()
- 测试
返回的错误信息与我们预期的相同![]()
- 但是这样做似乎也有一些重复的代码,就比如判断
BindingResult
在每个api方法中都会出现,可以使用全局异常拦截,优化这个地方
定义异常拦截类,注意
MethodArgumentNotValidException
是使用@RequestBody
校验失败会返回该异常![]()
代码:
package com.example.web.error;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.stream.Collectors;
@RestControllerAdvice
@RestController
public class GlobalExceptionHandler {
@ExceptionHandler(value = MethodArgumentNotValidException.class)
public String methodParamNotValid(HttpServletRequest req, MethodArgumentNotValidException ex){
List<ObjectError> allErrors = ex.getBindingResult().getAllErrors();
return allErrors.stream().map(ObjectError::getDefaultMessage).collect(Collectors.joining(";"));
}
@ExceptionHandler(value = BindException.class)
public String methodParamNotValid(HttpServletRequest req, BindException ex){
List<ObjectError> allErrors = ex.getBindingResult().getAllErrors();
return allErrors.stream().map(ObjectError::getDefaultMessage).collect(Collectors.joining(";"));
}
}
- 配置validator
可以把返回信息写在配置文件中,更方便管理
![]()
配置文件的位置:
![]()
代码:
package com.example.configuration.validation;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import javax.validation.Validator;
import java.nio.charset.StandardCharsets;
@Configuration
public class ValidatorConfig {
@Bean
public Validator getValidator(){
LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean();
localValidatorFactoryBean.setValidationMessageSource(getMessageSource());
return localValidatorFactoryBean;
}
private ResourceBundleMessageSource getMessageSource(){
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setDefaultEncoding(StandardCharsets.UTF_8.name());
messageSource.setBasename("validator/message");
return messageSource;
}
}
- 修改注解中的message
因为现在错误信息配置在对应的文件中,所以把错误信息对应的编码填上去
![]()
配置文件:
![]()
- 测试
controller中的方法更加清爽:![]()
测试木有任务问题
![]()
- 你可能有一点点 好奇为啥validator为啥会有两个配置文件,相信你从配置文件的名字已经看出倪端,是用来国际化的。
写一下配置文件![]()
使用postman请求,注意,语言要选择us:![]()
网友评论