Open
Description
1.背景
实际开发中对参数进行检查,是常见
比如如下代码
/**
* 参数检查测试(传统做法)
*
* @param dto
* @return
*/
@GetMapping("/paramCheckOld")
public BaseResponse paramCheckOld(@RequestBody UserDTO dto) {
// 参数检查
if (StrUtil.isEmpty(dto.getWeChat())) {
return ResponseBuilder.failed("微信号为空");
}
if (StrUtil.isEmpty(dto.getName())) {
return ResponseBuilder.failed("姓名为空");
}
if (dto.getStatus() != null
|| dto.getStatus() != -1
|| dto.getStatus() != 0
|| dto.getStatus() != 1) {
return ResponseBuilder.failed("状态为-1,0,1或者null");
}
// .....如果参数很多这里必然后崩溃..........
// 调用业务方法
// 响应结果
System.out.println("dto=" + dto);
return ResponseBuilder.success("统一参数检查.....");
}
但是正确的做法应该是,这里其实只使用了一个@validated注解就搞定了,太方便了.....
/**
* 统一参数检查(牛逼的做法)
*
* @param dto
* @return
*/
@GetMapping("/paramCheck")
public BaseResponse paramCheck(@RequestBody @Validated UserDTO dto) {
// 参数检查(已检查)
// 调用业务方法
// 响应结果
System.out.println("dto=" + dto);
return ResponseBuilder.success("统一参数检查.....");
}
2.步骤
步骤一:引入jar包
<!-- 统一参数校验-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
步骤二:参数上贴标签
package com.ldp.user.entity.dto;
import com.ldp.user.common.validation.EnumValue;
import lombok.Data;
import javax.validation.constraints.NotBlank;
/**
* @author 姿势帝-博客园
* @address https://www.cnblogs.com/newAndHui/
* @WeChat 851298348
* @create 01/01 4:00
* @description
*/
@Data
public class UserDTO {
@NotBlank(message = "微信号不能为空")
private String weChat;
@NotBlank(message = "姓名不能为空")
private String name;
/**
* 年龄
*/
private Integer age;
/**
* 状态
* -1:冻结用户 ,0:正常用户, 1:没有实名认证
*/
@EnumValue(intValues = {-1, 0, 1}, message = "状态为-1,0,1或者null")
private Integer status;
/**
* 地址
*/
private String address;
}
步骤三:控制层方法上贴标签(当然在其他方法上也可以用的,只是一般我们用在控制层上)
/**
* 统一参数检查(牛逼的做法)
*
* @param dto
* @return
*/
@GetMapping("/paramCheck")
public BaseResponse paramCheck(@RequestBody @Validated UserDTO dto) {
// 参数检查(已检查)
// 调用业务方法
// 响应结果
System.out.println("dto=" + dto);
return ResponseBuilder.success("统一参数检查.....");
}
步骤四:统一参数检查不通过时提示消息获取
/**
* 参数异常捕获
*
* @param ex
* @return
*/
@ResponseBody
@ExceptionHandler(value = ConstraintViolationException.class)
public Object constraintViolationExceptionHandler(ConstraintViolationException ex) {
Set<ConstraintViolation<?>> constraintViolations = ex.getConstraintViolations();
Iterator<ConstraintViolation<?>> iterator = constraintViolations.iterator();
List<String> msgList = new ArrayList<>();
while (iterator.hasNext()) {
ConstraintViolation<?> cvl = iterator.next();
msgList.add(cvl.getMessageTemplate());
}
return ResponseBuilder.failed(msgList.toString());
}
@ExceptionHandler(BindException.class)
@ResponseBody
public Object getBindException(BindException ex) {
List<ObjectError> objectErrors = ex.getBindingResult().getAllErrors();
if (!CollectionUtils.isEmpty(objectErrors)) {
StringBuilder msgBuilder = new StringBuilder();
for (ObjectError objectError : objectErrors) {
msgBuilder.append(objectError.getDefaultMessage()).append(",");
}
String errorMessage = msgBuilder.toString();
if (errorMessage.length() > 1) {
errorMessage = errorMessage.substring(0, errorMessage.length() - 1);
}
return ResponseBuilder.failed(errorMessage);
}
return ResponseBuilder.failed(ex.getMessage());
}
步骤五测试
@Test
void paramCheck() {
String url = urlLocal + "/userOrder/paramCheck";
System.out.println("请求地址:" + url);
HttpRequest request = HttpUtil.createRequest(Method.GET, url);
Map<String, Object> map = new TreeMap<>();
// 业务参数
// map.put("weChat", "851298348");
// map.put("name", "李东平");
map.put("age", "18");
map.put("status", "0");
map.put("address", "四川成都");
// 公用参数
map.put("appid", "1001");
map.put("sequenceId", "seq" + System.currentTimeMillis());
map.put("timeStamp", System.currentTimeMillis());
map.put("sign", signApi(map, "123456"));
String param = JSON.toJSONString(map);
request.body(param);
System.out.println("请求参数:" + param);
request.header("Authorization", token);
request.setConnectionTimeout(60 * 1000);
String response = request.execute().body();
System.out.println("请求结果:" + response);
}
测试结果:
{"message":"微信号不能为空,姓名不能为空","code":900}
3.常用检查规则注解
JSR提供的校验注解:
@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(regex=,flag=) 被注释的元素必须符合指定的正则表达式
Hibernate Validator提供的校验注解:
@NotBlank(message =) 验证字符串非null,且trim后长度必须大于0
@Email 被注释的元素必须是电子邮箱地址
@Length(min=,max=) 被注释的字符串的大小必须在指定的范围内
@NotEmpty 被注释的字符串的必须非空
@Range(min=,max=,message=) 被注释的元素必须在合适的范围内
4.自定义检查规则注解
如果这些注解还不能满足我们的需求,那么我么可以自己定义满足自己业务规则的注解
这里以自定义一个枚举值检查的注解,这个在实际生产中用的非常普遍
比如在传入用户状态时,只嗯传入-1,0,1或者null,其都是参数不合法的检查注解
https://www.cnblogs.com/newAndHui/p/14185807.html