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

2022-03-05 00:00:00 拦截 优雅 层中

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

测试结果

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

    原文作者:m0_54222377
    原文地址: https://blog.csdn.net/m0_54222377/article/details/113792585
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。

相关文章