基于SpringBoot的Java Web项目全局异常捕获

前面有介绍基于Spring的项目如何全局异常捕获,通过RESTful接口形式返回,其实基于SpringBoot的项目处理起来更加的方便。

代码实现


@RestControllerAdvice
public class GlobalExceptionHandler {
    private static Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
    @Value("${project.developer.email}")
    private String developerEmails;
    public static final String SEPATATOR = ",";
    @ExceptionHandler(value = Exception.class)
    public String resolveException(HttpServletRequest request, Exception exception) {
        exception.printStackTrace();
        StringBuilder html = new StringBuilder();
        String msg = exception.getMessage();
        if(Strings.isNotEmpty(msg)){
            html.append("<h1>").append(exception.getMessage()).append("</h1>").append("</br>");
        }
        StringBuilder params = new StringBuilder();
        int index = 0;
        for (Object param : request.getParameterMap().keySet()) {
            params.append((index++ == 0 ? "" : "&") + param + "=");
            params.append(request.getParameter((String) param));
        }
        html.append("<h2>").append("-------------------------------------请求信息------------------------------------").append("</h2>");
        html.append("请求参数:").append(params.toString()).append("</br>");
        html.append("请求代理:").append(request.getHeader("user-agent")).append("</br>");
        html.append("请求URI").append(request.getRequestURI()).append("</br>");
        html.append("<h2>").append("-------------------------------------异常信息------------------------------------").append("</h2>");
        StackTraceElement[] traceArray = exception.getStackTrace();
        for (StackTraceElement ele : traceArray){
            html.append(ele.toString()).append("</br>");
        }
        getThrowableTrace(exception.getCause(),html);
//        RobotMail.buildMail().subject("koit.cc Exception").addHtml(html.toString()).to(developerEmails.split(SEPATATOR)).send();
        return RestRet.fail(msg);
    }
    private void getThrowableTrace(Throwable throwable,StringBuilder sb){
        if(throwable != null){
            String msg = throwable.getMessage();
            if (Strings.isNotEmpty(msg)) {
                sb.append("<h3>").append(msg).append("</h3>").append("</br>");
            }
            for (StackTraceElement ele : throwable.getStackTrace()){
                sb.append(ele.toString()).append("</br>");
            }
            getThrowableTrace(throwable.getCause(),sb);
        }
    }
}

说明

  • 需加@RestControllerAdvice注解,才能注册为组件被Spring自动扫描
  • resolveException方法内实现处理异常的逻辑,需要加注解@ExceptionHandler(value = Exception.class),其中value可以自己定义需要处理的异常类,比如这里处理所有的Exception,包含其子类。实际可用收窄一些,比如只处理自定义的业务异常。
  • 处理方法内部我这里是打印输出异常信息、通过邮件发送异常信息和请求信息、以及通过RESTful风格返回接口。
  • 当然可用拥有多个处理异常的方法,比如
    @ExceptionHandler(value = ServiceException.class)
      public String resolveServiceException(HttpServletRequest request, ServiceException exception) {
      // TODO
    }
    
    实现起来是不是非常的简单?有了全局异常的处理,如果万一程序抛出的异常,也能给前端一个友好的返回,而不是直接将异常显示在前台或者系统无任何人性化的提示。
© 2019 FunGa技术札记 All Rights Reserved. 本站访客数人次 本站总访问量
Theme by hiero