网站首页 > 技术文章 正文
导读
我们开发项目的时候,如何判断请求过来的参数非空,长度大小等情况,是不是在代码里面写非空判断,校验长度,如下代码。
如果这个UserVO这个对象有10个字段都要做非空判断,那么这个代码就会变成很多且非常不优雅,那么我们就要想办法解决这个,因此spring为我们提供了validation框架,在springboot框架使用更加简单,validation框架都是已经整合到springboot中了。
新建一个springboot-validation项目
依赖包如下:
<!-- 1、依赖springboot包 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<!-- 2、springboot web包,已经整合好了validation框架 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- lombok框架 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
新建一个ResponseVO类
该类是统一返回Json格式封装类,例如要统一返回格式:
{
"code":"200", //状态码
"msg":"操作成功", //消息
"data":null //数据
}
类如下:
/**
* 统一响应VO
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ResponseVO<T> {
/**
* 状态码
*/
String code;
/**
* 状态信息
*/
String msg;
/**
* 返回数据对象
*/
T data;
/**
* 定义一个静态方法,返回成功状态码
* @return 响应对象
*/
public static ResponseVO success(){
return new ResponseVO("200","操作成功",null);
}
/**
* 定义一个静态方法,返回失败状态码,以及指定失败信息
* @param msg 失败信息
* @return 响应对象
*/
public static ResponseVO fail(String msg){
return new ResponseVO("999",msg,null);
}
}
新建一个UserVO类
该类就用到了validation框架注解
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
@Data
public class UserVO {
@NotBlank(message = "用户名不能为空")
String userName;
@NotBlank(message = "密码不能为空")
@Size(min = 6,message = "密码长度最小六位")
String password;
@NotNull(message = "年龄不能为空")
Integer age;
}
相关注解说明:
@AssertFalse
新建UserController类
@Controller
@Slf4j
public class UserController {
/**
* 新增用户对象
*/
@GetMapping("addUser")
@ResponseBody
public ResponseVO addUser(@Validated UserVO userVO){
log.info("新增用户对象={}",userVO);
//返回成功状态码
return ResponseVO.success();
}
}
@Validated 是必须注解,就是把UserVO对象用validation框架校验参数,当提交数据的时候,会自动校验UserVO里面属性非空注解。
新建SpringBootValidApp启动类
@SpringBootApplication
public class SpringBootValidApp {
public static void main(String[] args) {
SpringApplication.run(SpringBootValidApp.class,args);
}
}
启动服务成功后,浏览器访问地址,设置请求参数空值测试
http://127.0.0.1:8080/addUser?userName=&password=&age=
发现控制台出现以下异常,说明校验生效了
2020-10-23 14:38:49.123 WARN 39904 --- [nio-8080-exec-9] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 4 errors
Field error in object 'userVO' on field 'password': rejected value []; codes [NotBlank.userVO.password,NotBlank.password,NotBlank.java.lang.String,NotBlank]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [userVO.password,password]; arguments []; default message [password]]; default message [密码不能为空]
Field error in object 'userVO' on field 'password': rejected value []; codes [Size.userVO.password,Size.password,Size.java.lang.String,Size]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [userVO.password,password]; arguments []; default message [password],2147483647,6]; default message [密码长度最小六位]
Field error in object 'userVO' on field 'userName': rejected value []; codes [NotBlank.userVO.userName,NotBlank.userName,NotBlank.java.lang.String,NotBlank]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [userVO.userName,userName]; arguments []; default message [userName]]; default message [用户名不能为空]
Field error in object 'userVO' on field 'age': rejected value [null]; codes [NotNull.userVO.age,NotNull.age,NotNull.java.lang.Integer,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [userVO.age,age]; arguments []; default message [age]]; default message [年龄不能为空]]
浏览器页面显示错误信息
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Fri Oct 23 14:38:49 CST 2020
There was an unexpected error (type=Bad Request, status=400).
Validation failed for object='userVO'. Error count: 4
现在只是看到了校验失败信息,那么如何把错误信息返回到页面当中呢?这个是我们下面要解决的问题
新建一个全局异常类
该异常类核心用到了一个注解:@RestControllerAdvice,该数据就是监听Controller类如果有异常的时候,通知一下,然后使用:@ExceptionHandler,来处理特定异常,从而根据异常对象,解析异常信息,封装成:ResponseVO,返回到客户端。
/**
* 全局公共异常帮助类
*/
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
/**
* Get 非body请求 ,用BindException
* @RequestBody @Valid 用MethodArgumentNotValidException
* 校验参数异常,显示输出具体字段错误列表
*/
@ExceptionHandler(value= {BindException.class,MethodArgumentNotValidException.class})
public Object validatorbindException(Throwable e,HttpServletRequest req){
String uri=req.getRequestURI();
log.error("请求URI={},校验参数不通过",uri);
BindingResult bindingResult=null;
if(e instanceof BindException) {
bindingResult=((BindException)e).getBindingResult();
}else if(e instanceof MethodArgumentNotValidException) {
bindingResult=((MethodArgumentNotValidException)e).getBindingResult();
}
StringBuilder msg=new StringBuilder("");
try {
if(bindingResult.hasErrors()) {
List<FieldError> fieldErrors=bindingResult.getFieldErrors();
for (FieldError fieldError:fieldErrors) {
msg.append(", ").append(fieldError.getDefaultMessage());
log.error("请求URI={},字段={},校验信息={}",uri,fieldError.getField(),fieldError.getDefaultMessage());
}
msg.deleteCharAt(0);
}
} catch (Throwable tx) {
log.error("转换校验参数异常",tx);
}
return ResponseVO.fail(msg.toString());
}
}
重新启动服务,重新做以上非空访问测试,页面显示如下信息,证明异常返回页面处理成功
{
"code":"999",
"msg":" 密码长度最小六位, 用户名不能为空, 年龄不能为空, 密码不能为空",
"data":null
}
测试正常数据请求
访问地址:
http://127.0.0.1:8080/addUser?userName=xiaoming&password=123456&age=12
测试结果:
{
"code":"200",
"msg":"操作成功",
"data":null
}
总结
Sringboot validation校验请求参数,大大简化了在代码里面做非空判断,大大的提高了工作效率,即优雅又漂亮的代码,从此再也不用加班了,你Get到了吗?如果有疑问,欢迎大家讨论或者与我沟通。
猜你喜欢
- 2024-10-13 谈谈springboot 获取前端json数据几种方法
- 2024-10-13 在Spring Boot中如何获取到Request对象?
- 2024-10-13 SpringBoot:如何优雅地进行响应数据封装、异常处理
- 2024-10-13 SpringBoot实现接口防抖的几种方案,杜绝重复提交
- 2024-10-13 @PostMapping @GetMapping注解 postmapping注解接收参数
- 2024-10-13 如何在SpringBoot中动态过滤JSON响应正文
- 2024-10-13 WebSocket 集群解决方案 websocket500
- 2024-10-13 SpringBoot跨系统调用接口方案 springboot跨越设置
- 2024-10-13 SpringBoot如何优雅的进行参数校验(一)
- 2024-10-13 IntelliJ IDEA必装插件以及SpringBoot使用小技巧合集
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- oraclesql优化 (66)
- 类的加载机制 (75)
- feignclient (62)
- 一致性hash算法 (71)
- dockfile (66)
- 锁机制 (57)
- javaresponse (60)
- 查看hive版本 (59)
- phpworkerman (57)
- spark算子 (58)
- vue双向绑定的原理 (68)
- springbootget请求 (58)
- docker网络三种模式 (67)
- spring控制反转 (71)
- data:image/jpeg (69)
- base64 (69)
- java分页 (64)
- kibanadocker (60)
- qabstracttablemodel (62)
- java生成pdf文件 (69)
- deletelater (62)
- com.aspose.words (58)
- android.mk (62)
- qopengl (73)
- epoch_millis (61)
本文暂时没有评论,来添加一个吧(●'◡'●)