如何在controller层中优雅的拦截异常

如何在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方式返回给前端

还要记得配置


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);
        }
    }
}

测试结果

如何在controller层中优雅的拦截异常_第1张图片
如何在controller层中优雅的拦截异常_第2张图片

你可能感兴趣的:(java,exception,spring)