1 、普通校验
添加依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency>
修改一下idea的配置,防止提示信息乱码
项目创建成功后,查看LocalValidatorFactoryBean类的源码,发现默认的ValidationMessageSource(校验出错时的提示文件)是resources目录下的ValidationMessages.properties 文件,如下:
因此在resource目录下创建ValidationMessages.properties文件,内容如下:
city.cityname.notnull=城市名称必填city.cityInitial.notnull=城市首字母必填city.cityInitial.size=首字母长度为1
实体类中配置数据校验
public class City implements Serializable {private static final long serialVersionUID = -40142021265771170L;/*** 主键 自增长*/private Integer id;/*** 城市名称*/@NotNull(message="{city.cityname.notnull}")private String cityName;/*** 城市名称拼音*/private String cityNameSpell;/*** 城市首字母*/@NotNull(message="{city.cityInitial.notnull}")// @DecimalMin(value = "1", message = "{city.cityInitial.size}")// @DecimalMax(value = "1", message = "{city.cityInitial.size}")@Length(min=1,max=1,message = "{city.cityInitial.size}")private String cityInitial;private Date createTime;private String creator;private Date operateTime;private String operator;
控制器中加入校验StudentController中加入@Validated:
@PostMapping("add")public HttpResult add(@Validated City city){return HttpResult.ok("保存城市信息成功");}
默认返回的信息
{"timestamp": "2020-07-27T07:08:41.933+0000","status": 400,"error": "Bad Request","errors": [{"codes": ["NotNull.city.cityName","NotNull.cityName","NotNull.java.lang.String","NotNull"],"arguments": [{"codes": ["city.cityName","cityName"],"arguments": null,"defaultMessage": "cityName","code": "cityName"}],"defaultMessage": "城市名称不允许为空","objectName": "city","field": "cityName","rejectedValue": null,"bindingFailure": false,"code": "NotNull"}],"message": "Validation failed for object='city'. Error count: 1","path": "/city/add"}
使用BindingResult保存校验出错时的的信息 ,StudentController加入
@PostMapping("/add")public HttpResult add(@Validated Student student, BindingResult result){List<String> errorList=new ArrayList<>();if(result.hasErrors()){List<ObjectError> list=result.getAllErrors();for(ObjectError objectError:list){errorList.add(objectError.getDefaultMessage());}//下面使用lambda表达式和上面的for作用一样// result.getAllErrors().forEach( objectError -> errorList.add(objectError.getDefaultMessage()));}if(!errorList.isEmpty()){return HttpResult.error(errorList);}return HttpResult.ok("保存城市信息成功");}
返回信息
{"code": 1000,"msg": null,"data": ["首字母长度为1","城市名称必填"]}
2 全局异常处理类(BindException)
可以在controller方法中将BindingResult result参数进行删除,进行统一处理
/*** 定义全局异常类* 全局异常控制类加入拦截*/@RestControllerAdvicepublic class GlobalExceptionHandle {@ExceptionHandler(value = BindException.class)public HttpResult bindExceptionErrorHandler(BindException ex) throws Exception {List<String> errorList=new ArrayList<>();if(ex.hasErrors()){List<ObjectError> list=ex.getAllErrors();for(ObjectError objectError:list){errorList.add(objectError.getDefaultMessage());}// ex.getAllErrors().forEach( objectError -> errorList.add(objectError.getDefaultMessage()));}if(!errorList.isEmpty()){return HttpResult.error(errorList);}return HttpResult.error();}}
3 、常用注解
4 、全局异常处理类
/*** 定义全局异常类* 全局异常控制类加入拦截*/@RestControllerAdvicepublic class GlobalExceptionHandle {@ExceptionHandler(value = BindException.class)public HttpResult bindExceptionErrorHandler(BindException ex) throws Exception {List<String> errorList = new ArrayList<>();if (ex.hasErrors()) {List<ObjectError> list = ex.getAllErrors();for (ObjectError objectError : list) {errorList.add(objectError.getDefaultMessage());}//lambda 表达式写法,和上面的for循环一样// ex.getAllErrors().forEach( objectError -> errorList.add(objectError.getDefaultMessage()));}if (!errorList.isEmpty()) {return HttpResult.error(errorList);}return HttpResult.error();}// -----------------------Request------------------------------------------------@ExceptionHandler(HttpRequestMethodNotSupportedException.class)@ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)public HttpResult handleMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {return HttpResult.error("错误的请求方式");}@ExceptionHandler(MissingServletRequestParameterException.class)@ResponseStatus(HttpStatus.OK)public HttpResult handleMissingParameterException(MissingServletRequestParameterException e) {return HttpResult.error("参数缺失");}// ----------------------------data--------------------------------------@ExceptionHandler(DataAccessException.class)@ResponseStatus(HttpStatus.OK)public HttpResult handlerDataAccessException(DataAccessException e) {return HttpResult.error(31000, "数据库异常");}@ExceptionHandler(EmptyResultDataAccessException.class)@ResponseStatus(HttpStatus.OK)public HttpResult handleDataEmptyException(EmptyResultDataAccessException e) {return HttpResult.error("数据不存在");}@ExceptionHandler(DuplicateKeyException.class)@ResponseStatus(HttpStatus.OK)public HttpResult handleDataDualException(DuplicateKeyException e) {return HttpResult.error("数据重复插入");}// @ExceptionHandler(MultipartException.class)// @ResponseStatus(HttpStatus.OK)// public HttpResult handlerMultipartException(Throwable ex) {// String message = "文件上传错误";// MultipartException mEx = (MultipartException) ex;// if (ex.getCause() != null) {// Throwable cause = ex.getCause().getCause();// if (cause instanceof SizeLimitExceededException) {// SizeLimitExceededException flEx = (FileUploadBase.SizeLimitExceededException) cause;// float permittedSize = flEx.getPermittedSize() / 1024 / 1024;// message = "文件大小超过" + permittedSize + "MB";// } else if (cause instanceof FileSizeLimitExceededException) {// FileSizeLimitExceededException flEx = (FileSizeLimitExceededException) mEx.getCause().getCause();// float permittedSize = flEx.getPermittedSize() / 1024 / 1024;// message = "文件大小超过" + permittedSize + "MB";// }// }//// return HttpResult.error(message);// }// ---------All--------------------------------@ExceptionHandler(Exception.class)@ResponseStatus(HttpStatus.OK)public HttpResult handlerException(Exception e) {return HttpResult.error(30000, "系统异常");}}
