spring mvc 下的参数校验并统一处理返回结果
2018-10-14 本文已影响9人
熬夜的猫头鹰
依赖
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.3.5.Final</version>
</dependency>
常见的使用实例
//该参数必须为空
@Null(message = "无需ID")
private Integer id;
//根据正则校验手机号是否是由数字组成
@Pattern(regexp = "^\\d{11}$", message = "手机格式不正确,不是11位")
private String telephone;
//校验该对象是否为null
//对于String来说,空字符串可通过校验,所以String应该使用@NotBlank进行校验,此处仅做示例而已。
@NotNull(message = "联系人不能为空")
private String friendName;
//校验对象是否是空对象,可用于Array,Collection,Map,String
@NotEmpty(message = "家庭成员不能为空")
private List families;
//校验长度,可以用于Array,Collection,Map,String
@Size(min = 4, max = 8, message = "用户名长度错误 by size")
//校验长度,只能用于String
@Length(min = 4, max = 8, message = "用户名长度错误 by length")
private String username;
//javax校验
@Max(value = 200, message = "年龄一般不会超过200 by max")
@Min(value = 1, message = "年龄一般不能小于1 by min")
//hibernate校验,效果等同
@Range(min = 0, max = 200, message = "年龄范围在0-200之间 by range")
private Integer age;
//校验参数是否是False, 相反的是@AssertTrue
@AssertFalse(message = "用户初始化无需冻结")
private Boolean lock;
//String专用
@NotBlank(message = "密码不能为空")
@Size(min = 6, max = 12, message = "密码长度不对")
private String password;
//使用自定义校验注解->校验时间
@Past(message = "生日只能为以前的时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
private Date birth;
//校验Email
@Email(message = "邮件地址不正确")
private String email;
普通参数的使用方法
- 在类上加@Validated注解
- 在参数上加上校验注解
分组校验
我们有一个用户DTO,其中有id,username两个属性。当保存时,id不需要有值,由数据库自动生成,我们使用@Null注解校验。当更新时,id需要有值,根据ID去更新用户名,我们使用@NotNull注解校验。无论是保存用户还是更新用户,都需要校验用户名,我们使用@NotBlank注解校验。
public class UserGroupValidDTO {
public interface SaveGroup extends Default {}
public interface UpdateGroup extends Default {}
@Null(groups = {SaveGroup.class}, message = "不需要传入用户ID")
@NotNull(groups = {UpdateGroup.class}, message = "用户ID不能为空")
private Integer id;
@NotBlank(message = "用户名不能为空")
private String username;
//Setter Getter ...
}
定义相应类型的公开接口(SaveGroup,UpdateGroup),给每个校验注解指定groups属性,如果不指定则默认为javax.validation.groups.Default.class。
UserController
@Validated
@RestController
@RequestMapping(value = "/user")
public class UserController {
/**
* 分组校验:保存用户,不能传ID
*/
@PostMapping("/save")
public void validSaveUser(@RequestBody @Validated(value = UserGroupValidDTO.SaveGroup.class) UserGroupValidDTO userDTO) {
//save user
}
/**
* 分组校验:更新用户信息,需要传ID
*/
@PostMapping("/update")
public void validUpdateUser(@RequestBody @Validated(value = UserGroupValidDTO.UpdateGroup.class) UserGroupValidDTO userDTO) {
//update user
}
}
自定义注解
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PastTimeValidate.class)
public @interface PastDate {
String message();
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
}
编写校验规则
校验规则也就是枚举PastDate中指定的validateBy属性
public class PastTimeValidate implements ConstraintValidator<PastDate, LocalDateTime> {
@Override
public void initialize(PastDate constraintAnnotation) {
log.info("init enum PastDate");
}
@Override
public boolean isValid(LocalDateTime localDateTime, ConstraintValidatorContext context) {
return localDateTime.isBefore(LocalDateTime.now()) ? true : false;
}
}
依赖异常统一返回json结果
@ControllerAdvice
public class GlobalExceptionHandler {
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(BindException.class)
@ResponseBody
public Object paramCheckExceptionHandler(BindException e) {
BindingResult bindingResult = e.getBindingResult();
return CommonJsonResultBuilder.builder().code(400).data("error", getErrors(bindingResult)).message("参数错误").build();
}
private Map<String, Object> getErrors(BindingResult result) {
Map<String, Object> map = new HashMap<>();
List<FieldError> list = result.getFieldErrors();
for (FieldError error : list) {
map.put(error.getField(), error.getDefaultMessage());
}
return map;
}
}
controller
@Slf4j
@RestController
public class VideoController {
@RequestMapping("video/edit")
public CommonJsonResult add(@Valid VideoVO videoVO) {
}
}
VideoVO
public class VideoVO implements Serializable {
private Integer id;
private Integer shopId;
@NotEmpty(message = "视频标题不能为空")
private String title;
@NotNull(message = "视频Id不能为空")
private Long videoId;
@NotEmpty(message = "视频路径不能为空")
private String videoUrl;
@NotEmpty(message = "视频封面图不能为空")
private String coverPic;
@NotNull(message = "视频顺序不能为空")
private Integer orderNo;
@NotNull(message = "视频大小不能为空")
private Long videoSize;
@NotNull(message = "视频时长不能为空")
private Long timeSize;
}
返回结果:
{
"code": 400,
"success": false,
"message": "参数错误",
"data": {
"error": {
"timeSize": "视频时长不能为空",
"orderNo": "视频顺序不能为空",
"videoUrl": "视频路径不能为空",
"videoId": "视频Id不能为空",
"coverPic": "视频封面图不能为空",
"title": "视频标题不能为空",
"videoSize": "视频大小不能为空"
}
}
}