使用 @ControllerAdvice + @ExceptionHandler 注解 這兩個(gè)注解功能可以百度哈,這邊只介紹下具體使用
- 平時(shí)使用中為了接口安全不想將一些不必要的異常返回出去,可以進(jìn)行一些處理統(tǒng)一封裝返回
- 一些程序報(bào)錯(cuò)信息不想讓用戶看到,比如by zero
這時(shí)需要全局異常來幫我們統(tǒng)一處理返回
比如針對不同業(yè)務(wù)拋出異常,需要手動(dòng)處理 try catch
public Object test(){
try {
//具體業(yè)務(wù)
return ResultBean.success();
}catch (ServiceException e){
return ResultBean.error(300,"網(wǎng)絡(luò)開小差了");
}
catch (Exception e){
return ResultBean.error(500,"系統(tǒng)錯(cuò)誤");
}
}
比如使用 @RequestParam
public Object test(@RequestParam Integer id,@RequestParam String name){
return userService.test(id,name);
}
這邊對入?yún)⒆隽讼拗?但是如果不做異常處理,會(huì)返回這樣的
image.png
這樣向外暴露了缺少id參數(shù),如果是比較重要的接口別人可以知道少了具體的參數(shù)名稱,可以一直試接口
針對這個(gè)異常統(tǒng)一處理后返回是這樣的:
{
"code": 300,
"msg": "請求失敗",
"data": null
}
不向外暴露具體異常信息,這邊列了幾個(gè)常用的,當(dāng)然根據(jù)業(yè)務(wù)可以自定義設(shè)定處理更多異常
@RestControllerAdvice
@Slf4j
public class ExceptionHandler {
/**
* 針對@RequestParam 拋出的限制異常,統(tǒng)一返回
* @param e
* @return
*/
@org.springframework.web.bind.annotation.ExceptionHandler({MissingServletRequestParameterException.class})
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ResultBean validationException(MissingServletRequestParameterException e){
log.error("缺少請求參數(shù):參數(shù)名:{}->類型:{}",e.getParameterName(),e.getParameterType());
//異常信息可以自定義返回
return ResultBean.error("請求失敗");
}
/**
* 手動(dòng)拋出的自定義異常,統(tǒng)一返回
* @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校驗(yàn)不通過的請求
*/
@org.springframework.web.bind.annotation.ExceptionHandler({MethodArgumentNotValidException.class})
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ResultBean validationException(MethodArgumentNotValidException e) {
dealBindingResult(e.getBindingResult());
return ResultBean.error("請求失敗");
}
/**
* 針對valid檢驗(yàn)參數(shù)不返回具體異常,統(tǒng)一返回
* @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());
}
}
}