使用 @ControllerAdvice + @ExceptionHandler 注解 这两个注解功能可以百度哈,这边只介绍下具体使用
- 平时使用中为了接口安全不想将一些不必要的异常返回出去,可以进行一些处理统一封装返回
- 一些程序报错信息不想让用户看到,比如by zero
这时需要全局异常来帮我们统一处理返回
比如针对不同业务抛出异常,需要手动处理 try catch
public Object test(){
try {
//具体业务
return ResultBean.success();
}catch (ServiceException e){
return ResultBean.error(300,"网络开小差了");
}
catch (Exception e){
return ResultBean.error(500,"系统错误");
}
}
比如使用 @RequestParam
public Object test(@RequestParam Integer id,@RequestParam String name){
return userService.test(id,name);
}
这边对入参做了限制,但是如果不做异常处理,会返回这样的
image.png
这样向外暴露了缺少id参数,如果是比较重要的接口别人可以知道少了具体的参数名称,可以一直试接口
针对这个异常统一处理后返回是这样的:
{
"code": 300,
"msg": "请求失败",
"data": null
}
不向外暴露具体异常信息,这边列了几个常用的,当然根据业务可以自定义设定处理更多异常
@RestControllerAdvice
@Slf4j
public class ExceptionHandler {
/**
* 针对@RequestParam 抛出的限制异常,统一返回
* @param e
* @return
*/
@org.springframework.web.bind.annotation.ExceptionHandler({MissingServletRequestParameterException.class})
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ResultBean validationException(MissingServletRequestParameterException e){
log.error("缺少请求参数:参数名:{}->类型:{}",e.getParameterName(),e.getParameterType());
//异常信息可以自定义返回
return ResultBean.error("请求失败");
}
/**
* 手动抛出的自定义异常,统一返回
* @param e
* @return
*/
@org.springframework.web.bind.annotation.ExceptionHandler
public ResultBean serviceException(ServiceException e){
return ResultBean.error(e.getCode(),e.getMsg());
}
/**
* Exception 异常返回
* @param e
* @return
*/
@org.springframework.web.bind.annotation.ExceptionHandler
public ResultBean serviceException(Exception e){
return ResultBean.error(e.getMessage());
}
/**
* 拦截 post application/json @valid校验不通过的请求
*/
@org.springframework.web.bind.annotation.ExceptionHandler({MethodArgumentNotValidException.class})
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ResultBean validationException(MethodArgumentNotValidException e) {
dealBindingResult(e.getBindingResult());
return ResultBean.error("请求失败");
}
/**
* 针对valid检验参数不返回具体异常,统一返回
* @param e
* @return
*/
@org.springframework.web.bind.annotation.ExceptionHandler({BindException.class})
public ResultBean validationException(BindingResult e) {
dealBindingResult(e);
return ResultBean.error("请求失败");
}
private void dealBindingResult(BindingResult e){
StringJoiner joiner = new StringJoiner(",");
if (e.hasErrors()){
e.getFieldErrors().forEach(fieldError -> {
joiner.add(fieldError.getField()+"->"+fieldError.getDefaultMessage());
});
log.error(joiner.toString());
}
}
}
网友评论