@Valid 注解 的验证之美 和验证类 异常捕获
@Valid 是JSR303 指定的标准 ,hibernate 对其做了实现。
<dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> <version>6.0.13.Final</version> </dependency>
1 使用 只要在 需要验证的 类 ,字段 方法,写上 验证注解,

2 然后在需要使用的地方加上 @Valid 就可以了

验证注解 解释:
需要注意的是 @NotNull 通用 ,@NotBlank 只能修饰String,@NotEmpty 只能修饰集合数组
| 限制 | 说明 |
|---|---|
| @Null | 限制只能为null |
| @NotNull | 限制必须不为null |
| @AssertFalse | 限制必须为false |
| @AssertTrue | 限制必须为true |
| @DecimalMax(value) | 限制必须为一个不大于指定值的数字 |
| @DecimalMin(value) | 限制必须为一个不小于指定值的数字 |
| @Digits(integer,fraction) | 限制必须为一个小数,且整数部分的位数不能超过integer,小数部分的位数不能超过fraction |
| @Future | 限制必须是一个将来的日期 |
| @Max(value) | 限制必须为一个不大于指定值的数字 |
| @Min(value) | 限制必须为一个不小于指定值的数字 |
| @Past | 限制必须是一个过去的日期 |
| @Pattern(value) | 限制必须符合指定的正则表达式 |
| @Size(max,min) | 限制字符长度必须在min到max之间 |
| @NotEmpty | 验证注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0) |
| @NotBlank | 验证注解的元素值不为空(不为null、去除首位空格后长度为0),不同于@NotEmpty,@NotBlank只应用于字符串且在比较时会去除字符串的空格 |
| 验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式 |
备注:@Valid 目前默认只在 SpringMvc 的 控制器有效,并且这样写也是无效的 。
1 controller 非顶层方法,也无效

2 service 层也是无效的。

使用验证的一些注意事项
1 @Valid 和 @Validated 效果类似,但是有写时候不一样
2 在对象里面如果对象属性没有验证,而属性的属性需要验证,需要用 @Valid ,不然验证会中断
3 @NotNull 修饰方法参数的时候,需要在参数方法所在类上标注 @Validated 修饰,这时候 @Valid 不起作用
4 在标注方法参数的时候 @NotNull ,@NotBlank @NotEmpty 都一样,只是判断是否空
package com.lomi.controller;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import com.alibaba.fastjson.JSONObject;
import com.lomi.entity.in.validate.UserIn;
import com.lomi.entity.in.validate.UserPakeageIn;
import com.lomi.entity.out.FormatOut;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
/**
* 1 @Valid 和 @Validated 效果类似,但是有写时候不一样
* 2 在对象里面如果对象属性没有验证,而属性的属性需要验证,需要用 @Valid ,不然验证会中断
* 3 @NotNull 修饰方法参数的时候,需要在参数方法所在类上标注 @Validated 修饰,这时候 @Valid 不起作用
* 4 在标注方法参数的时候 @NotNull ,@NotBlank @NotEmpty 都一样,只是判断是否空
*
*
* @author ZHANGYUKUN
*
*
*/
@Api(tags="Validate测试")
@RestController
@RequestMapping(value = "/valid")
@Validated
public class ValidateController extends BaseController {
private static final Logger logger = LoggerFactory.getLogger(ValidateController.class);
@ApiOperation(value = "单参数")
@RequestMapping(value = "t1", method = { RequestMethod.POST })
@ResponseBody
public FormatOut t1(@NotBlank String s) throws Exception {
System.out.println( JSONObject.toJSONString( s ) );
return null;
}
@ApiOperation(value = "对象")
@RequestMapping(value = "t2", method = { RequestMethod.POST })
@ResponseBody
public String t2(@RequestBody @Validated UserIn in) throws Exception {
System.out.println( JSONObject.toJSONString( in ) );
return "OK";
}
@ApiOperation(value = "2层对象")
@RequestMapping(value = "t3", method = { RequestMethod.POST })
@ResponseBody
public FormatOut t2( @Valid UserPakeageIn in) throws Exception {
System.out.println( JSONObject.toJSONString( in ) );
return null;
}
}
下面是验证类
package com.lomi.entity.in.validate;
import java.util.List;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
public class UserPakeageIn {
@NotNull(message = "UserPakeageIn-id不能是null")
private Long id;
@NotBlank(message = "UserPakeageIn-name不能是null")
private String name;
//标注向下传递验证
@Valid
private UserIn user;
//@Valid 标记验证向下传递,但是自己不验证
//@Valid
private List<UserIn> users;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public UserIn getUser() {
return user;
}
public void setUser(UserIn user) {
this.user = user;
}
public List<UserIn> getUsers() {
return users;
}
public void setUsers(List<UserIn> users) {
this.users = users;
}
}
package com.lomi.entity.in.validate;
import java.util.List;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
public class UserIn {
@NotNull(message = "UserIn-id不能是null")
private Long id;
@NotBlank(message = "UserIn-name不能是null")
private String name;
@NotEmpty(message = "UserIn-skill不能是null")
private List<String> skill;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<String> getSkill() {
return skill;
}
public void setSkill(List<String> skill) {
this.skill = skill;
}
}
验证框架 异常验证是在进入请求方法之前,需要使用 @ControllerAdvice 而不是 @Component
并且还要标注 @ExceptionHandler(value = Throwable.class) 才能拦截到异常(如果拦截验证类的异常不需要)
package com.lomi.context;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
*
* 1 @Component 这种写法,没法处理 @Valid 的验证的异常,原因是 验证类异常出现在进入方法之前
* 2 如果需要拦截 验证异常需要 @ControllerAdvice ,可以拦截到进入,并且需要指定@ExceptionHandler(value = Throwable.class)
*
* 简单的统一异常处理
* @author ZHANGYUKUN
*
*/
//@Component
@ControllerAdvice
public class GlobalExceptionResolver implements HandlerExceptionResolver {
/**
*{"msg":true}
* @param request
* @param response
* @param handler
* @param ex
* @return
*/
@Override
@ExceptionHandler(value = Throwable.class)
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
System.out.println( "异常:" + ex );
String exMsg = null;
if( ex instanceof MethodArgumentNotValidException){
exMsg = ((MethodArgumentNotValidException)ex).getBindingResult().getFieldErrors().get(0).getDefaultMessage();
}else{
exMsg = ex.getMessage();
}
try {
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
PrintWriter writer = response.getWriter();
writer.write("{\"exMsg\":\""+ exMsg +"\"}" );
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}
//不能返回null,不要spring或默认返回一个
return new ModelAndView();
//return null;
}
}
能耍的时候就一定要耍,不能耍的时候一定要学。
--天道酬勤,贵在坚持posted on 2020-03-03 16:40 zhangyukun 阅读(576) 评论(0) 收藏 举报
浙公网安备 33010602011771号