1. 程式人生 > 其它 >如何在controller層中優雅的攔截異常

如何在controller層中優雅的攔截異常

技術標籤:javaexceptionspring

如何在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);
    }

}

具體異常攔截邏輯,程式碼非常簡單,學習下這種設計思路,優雅減少專案樣板程式碼

  1. 通過異常instanceof判斷出自定義異常,
  2. 然後取出異常碼,通過json方式返回給前端

還要記得配置

<bean id="exceptionResolver" class="com.ssm.interceptor.GlobalExceptionInterceptor"></bean>

4.測試demo

  1. controller
@Controller
public class HelloController {
    @Autowired
    UsersService usersService;
    
    @RequestMapping("/ex/{id}")
    public String testEX(@PathVariable("id") String id){
        usersService.doEX(id);
        return "OK";
    }
}
  1. 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);
        }
    }
}

測試結果

在這裡插入圖片描述
在這裡插入圖片描述