如何在controller層中優雅的攔截異常
阿新 • • 發佈:2021-02-13
如何在controller層中優雅的攔截異常
目標
- 學習全域性異常攔截器處理controller所有異常的返回封裝
- 定義列舉異常碼,優雅的設計自定義異常
1.自定義一個列舉類,用於存放異常程式碼
public enum BizError {
SYSTEM_ERROR("000","系統異常"),
INVALID_ERROR("001","非法引數"),
NOT_AUTHRIOZED("002","未授權");
//異常碼
private String errorCode;
//異常資訊
private String errorMessage;
private BizError(String errorCode,String errorMessage){
this.errorCode=errorCode;
this.errorMessage=errorMessage;
}
public String getErrorCode() {
return errorCode;
}
public void setErrorCode (String errorCode) {
this.errorCode = errorCode;
}
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
}
2.自定義一個異常類
public class MyException extends RuntimeException {
private BizError bizError;
private String message;
public MyException(BizError bizError){
super(bizError.getErrorMessage());
this.bizError = bizError;
}
public MyException(BizError bizError,String message){
super(StringUtils.isEmpty(bizError)?message:bizError.getErrorMessage());
this.bizError=bizError;
this.message=message;
}
public BizError getBizError() {
return bizError;
}
public void setBizError(BizError bizError) {
this.bizError = bizError;
}
@Override
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
3.自定義全域性異常攔截器
/**
* 全域性異常攔截器
*/
public class GlobalExceptionInterceptor implements HandlerExceptionResolver {
//日誌輸出
private Logger log = LoggerFactory.getLogger(GlobalExceptionInterceptor.class);
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
ModelAndView modelAndView = new ModelAndView();
System.out.println("全域性異常攔截");
try {
if(e instanceof MyException){
setJSONErrorResponse(httpServletResponse,((MyException) e).getBizError());
log.error(((MyException) e).getBizError().getErrorCode()+"---->"+((MyException) e).getBizError().getErrorMessage(),e);
}else {
setJSONErrorResponse(httpServletResponse,BizError.SYSTEM_ERROR);
e.printStackTrace();
}
} catch (IOException ioException) {
ioException.printStackTrace();
}
//返回一個空的modelAndView
return modelAndView;
}
private void setJSONErrorResponse(HttpServletResponse httpServletResponse, BizError bizError) throws IOException {
httpServletResponse.setContentType("application/json;charset=UTF-8");
httpServletResponse.setCharacterEncoding("UTF-8");
//拼接json
String retStr = "{\"errorCode\":\""+bizError.getErrorCode()+
"\",\"status\":\"filed\",\"errorMsg\":\""+bizError.getErrorMessage()+"\"}";
httpServletResponse.getWriter().write(retStr);
}
}
具體異常攔截邏輯,程式碼非常簡單,學習下這種設計思路,優雅減少專案樣板程式碼
- 通過異常instanceof判斷出自定義異常,
- 然後取出異常碼,通過json方式返回給前端
還要記得配置
<bean id="exceptionResolver" class="com.ssm.interceptor.GlobalExceptionInterceptor"></bean>
4.測試demo
- controller
@Controller
public class HelloController {
@Autowired
UsersService usersService;
@RequestMapping("/ex/{id}")
public String testEX(@PathVariable("id") String id){
usersService.doEX(id);
return "OK";
}
}
- service
@Service
public class UsersServiceImpl implements UsersService {
@Autowired
UsersDao usersDao;
@Override
public void doEX(String id) {
switch (id){
case "1":
throw new MyException(BizError.SYSTEM_ERROR);
case "2":
throw new MyException(BizError.INVALID_ERROR);
case "3":
throw new MyException(BizError.NOT_AUTHRIOZED);
}
}
}
測試結果