Spring-boot &异常处理

方法一:Spring Boot 将所有的错误默认映射到/error, 实现AbstractErrorController.

代码如下

@Controller
public class ErrorController extends AbstractErrorController {

    private static final String ERROR_PATH = "/error";
    Log log = LogFactory.getLog(ErrorController.class);

    @Autowired
    ObjectMapper objectMapper;

    public ErrorController() {
        super(new DefaultErrorAttributes());
    }

    @RequestMapping(ERROR_PATH)
    public ModelAndView getErrorPath(HttpServletRequest request, HttpServletResponse response) {
        Map<String, Object> model = Collections.unmodifiableMap(getErrorAttributes(
                request, false));
        Throwable cause = getCause(request);
        int status = (Integer) model.get("status");
        //错误信息
        String message = (String) model.get("message");
        //友好提示
        String errorMessage = getErrorMessage(cause);
        //请求地址
        String requestPath = (String) model.get("path");
        //后台打印日志信息方方便查错
        log.info(status + ":" + message, cause);
        log.info("requestPath" + ":" + requestPath);
        log.info(message, cause);
        response.setStatus(status);

        if (isJsonRequest(request)) {
            Result result = new Result();
            result.setCode(status);
            result.setMsg(message);
            writeJson(response, result);
            return null;
        } else {
            ModelAndView view = new ModelAndView("/error.html");
            view.addAllObjects(model);
            view.addObject("status", status);
            view.addObject("errorMessage", errorMessage);
            view.addObject("cause", cause);
            return view;
        }

    }

    /**
     * 判断客户端发起的是页面渲染请求还是Json 请求
     *
     * @param request
     * @return
     */
    protected boolean isJsonRequest(HttpServletRequest request) {
        String requestUri = request.getRequestURI();
        if (requestUri.endsWith(".json")) {
            return true;
        } else {
            return (request.getHeader("accept").contains("application/json") || (request.getHeader("X-Requested-With") != null
                    && request.getHeader("X-Requested-With").contains("XMLHttpRequest")));
        }
    }

    protected void writeJson(HttpServletResponse response, Object error) {
        response.setContentType("application/json;charset=utf-8");
        try {
            response.getWriter().write(objectMapper.writeValueAsString(error));
        } catch (IOException e) {

        }
    }

    /**
     * 获取自定义异常信息
     *
     * @param ex
     * @return
     */
    protected String getErrorMessage(Throwable ex) {
        if (ex instanceof MyException) {
            return ex.getMessage();
        }
        return "服务器错误,请联系管理员";
    }

    /**
     * 获取应用系统的异常信息
     *
     * @param request
     * @return
     */
    protected Throwable getCause(HttpServletRequest request) {
        Throwable error = (Throwable) request.getAttribute("javax.servlet.error.exception");
        if (error != null) {
            while (error instanceof ServletException && error.getCause() != null) {
                error = error.getCause();
            }
        }
        return error;
    }


    @Override
    public String getErrorPath() {
        return null;
    }

}

方法二:使用注解@ControllerAdvice

编写一个全局异常处理的类,这个类里面可以分门别类处理各种异常,可以对每一种异常提供一种自定义页面,使用户体验更加友好。

代码如下:

@ControllerAdvice
public class GlobalExceptionHandler {
    private static final String ERROR_PATH = "/error";
    Log log = LogFactory.getLog(ErrorController.class);
    @Autowired
    ObjectMapper objectMapper;

    @ExceptionHandler(value = Exception.class)
    public ModelAndView defaultErrorHandler(HttpServletRequest request, HttpServletResponse response,
                                            Exception e) throws Exception {
        log.info("GlobalExceptionHandler");
        if (isJsonRequest(request)) {
            Result result = new Result();
            result.setMsg(e.getMessage());
            writeJson(response, result);
            return null;
        } else {
            ModelAndView view = new ModelAndView("/error.html");
            view.addObject("errorMessage", e.getMessage());
            view.addObject("cause", e);
            return view;
        }
    }

方法三:添加自定义错误页面

1)html静态页面:在resources/public/error/ 下定义 如添加404页面: resources/public/error/404.html页面,中文注意页面编码 
2)模板引擎页面:在templates/error/下定义 如添加5xx页面: templates/error/5xx.ftl


猜你喜欢

转载自blog.csdn.net/yujq1993/article/details/80017689
今日推荐