@ControllerAdvice
@ControllerAdvice是在所选择的包下发生错误时,统一把错误都发送到标注了@ControllerAdvice的组件中来进行处理。
这样做当发生错误时,可以更好更快的处理错误。
下面为举例
@Slf4j
@RestControllerAdvice(basePackages = "com.qwf.gulimall.gulimallproduct.controller")
public class ControllerException {
@ExceptionHandler(value = MethodArgumentNotValidException.class)
public R handleValidException(MethodArgumentNotValidException e){
BindingResult bindingResult = e.getBindingResult();
Map<String,String> errorMap=new HashMap<>();
bindingResult.getFieldErrors().forEach((error)->{
errorMap.put(error.getField(),error.getDefaultMessage());
});
log.error("数据校验出现问题{},异常类型{}",e.getMessage(),e.getClass());
return R.error(BZCodeENum.VALID_EXCEPTION.getCode(),BZCodeENum.VALID_EXCEPTION.getMessage()).put("data",errorMap);
}
}
因为我下面当中的方法都需要返回 json 类型的数据,所以每个方法上面都需要标注@RequestBody。
而每个方法都标注太麻烦,所以当需要组件下面的每个方法都需要返回json数据时,组件可以使用@RestControllerAdvice注解,下面的方法就不需要标注@RequestBody注解了。
@RestControllerAdvice当中的basePackages 是当哪个地方发生错误需要返回。可以选择具体的某一个controller,或者是某个文件夹下所有的controller。
类下面对应的**@ExceptionHandler是发生了什么类型的错误,就会调用对应的方法。这里是发生MethodArgumentNotValidException错误时就会调用handleValidException()**方法。
下面的就是获取错误 e 然后获取e.getBindingResult() ,BindingResult 当中包含错误的默认消息以及发生错误的字段。
最好可以创建一个枚举,我创建了一个BZCodeENum用来存放错误代码以及对应的错误消息,这样发生错误直接返回代码可以更好的对应错误的类型。
我们可以在实体类entity当中设置@NotBlank(message = “描述不能为空”,groups = SaveGroup.class)之类的校验方法
@Data
@TableName("pms_brand")
public class PmsBrandEntity implements Serializable {
private static final long serialVersionUID = 1L;
/**
* Ʒ??id
*/
@NotEmpty(groups = UpdateGroup.class)
@TableId
private Long brandId;
/**
* Ʒ???
*/
@NotBlank(message = "品牌名不能为空",groups = SaveGroup.class)
private String name;
/**
* Ʒ??logo??ַ
*/
@URL(message = "LOGO的地址不是URL地址" ,groups = {SaveGroup.class,UpdateGroup.class})
@NotEmpty(message = "LOGO的URL地址不能为空",groups = SaveGroup.class)
private String logo;
/**
* ???
*/
@NotBlank(message = "描述不能为空",groups = SaveGroup.class)
private String descript;
/**
* ??ʾ״̬[0-????ʾ??1-??ʾ]
*/
@ListValue(Vals = {0,1},groups = SaveGroup.class)
private Integer showStatus;
/**
* ????????ĸ
*/
@NotEmpty(message = "首字母不能为空",groups = SaveGroup.class)
private String firstLetter;
/**
* ???
*/
@Min(value = 0,message = "排序的数值必须大于0",groups = {SaveGroup.class,UpdateGroup.class})
private Integer sort;
}
这里的groups是分组,我们可以创建一个接口例如SaveGroup和UpdateGroup,当中不需要编写任何代码。而controller传入参数时需要校验时,在方法传入参数前面加入@Validated(value = SaveGroup.class)就可以校验分组为savegroup的数据。
@RequestMapping("/save")
public R save(@Validated(value = SaveGroup.class) @RequestBody PmsBrandEntity pmsBrand/*, BindingResult result*/){
pmsBrandService.save(pmsBrand);
return R.ok();
}