SpringBoot Web/API的通用异常处理[嗡汤圆的小笔记]

来源:互联网 发布:mysql 特殊字符入库 编辑:程序博客网 时间:2024/05/01 05:48

view的异常处理

SpringBoot Web项目中对于view的默认错误信息页如下:
这里写图片描述

并不十分友好,因此需要对异常进行自定义处理,步骤如下:

  1. 建立@ControllerAdvice Bean。并分别为各异常类制定处理方式。为简单起见,本处仅对Exception(500错误)和NoHandlerFoundException(即404错误)进行处理
  2. 设置ServletDispatcher,允许404异常抛出(若不做此设置,NoHandlerFoundException不会被捕获)

代码如下:

/*STEP 1 : 声明@ControllerAdvice Bean*/@ControllerAdvicepublic class ErrorView {    @ExceptionHandler(value=Exception.class)    public ModelAndView defaultErrorHandler(HttpServletRequest request, Exception e) throws Exception {            ModelAndView view = new ModelAndView();            view.addObject("ERRORCODE", 500);            view.addObject("ERRORMSG", e.getMessage());            view.addObject("URL", request.getRequestURL());            view.setViewName("error");            return view;    }    @ExceptionHandler(value=NoHandlerFoundException.class)    public ModelAndView pageNoFoundHandler(HttpServletRequest request, Exception e) throws Exception {            ModelAndView view = new ModelAndView();            view.addObject("ERRORCODE", 404);            view.addObject("ERRORMSG", "页面未找到");            view.addObject("URL", request.getRequestURL());            view.setViewName("error");            return view;    }}/*STEP - 2 : 设置DispatcherServlet的404异常抛出*/@EnableScheduling@SpringBootApplicationpublic class WebProxy {    public static void main(String[] args) {        ApplicationContext ctx = SpringApplication.run(WebProxy.class, args);        // 自定义处理404异常        DispatcherServlet servlet = (DispatcherServlet) ctx.getBean("dispatcherServlet");        servlet.setThrowExceptionIfNoHandlerFound(true);    }}

在此基础上,制作一个异常页面error.html即可。代码如下(此处借助thymeleaf模板引擎):

<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"    xmlns:th="http://www.thymeleaf.org"    xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3"><head><title>ERROR</title><!-- 基本样式和库 --><div th:include="layout/common :: header"></div><div th:include="layout/common :: lib"></div><!-- 基本样式和库 --></head><body>    <header class="header">        <h1>            <a href="#" class="sel-station">错误页面</a>        </h1>    </header>    <div class="content" id="app">        <div class="media"><img th:src="@{/static/images/ico18.png}" width="100%" /></div>        <div class="lobby-place">            <section class="item">                <p th:text="'code:'+${ERRORCODE}">ERRORCODE</p>                <p th:text="'url:'+${URL}">                    URL                </p>                <P th:text="'msg:'+${ERRORMSG}">                    ERRORMSG                </P>                <a class="btn btn-block btn-primary" th:href="@{/view/index}">回首页</a>            </section>        </div>    </div></body></html>

显示效果如下:
这里写图片描述

增加API的异常处理

在增加通用处理前,首先先定义所有API的规范化数据结构。基本信息应包括:状态码statusCode, 状态信息statusMsg,数据data。代码如下:

public class ResultBean {    private int statusCode;    private String statusMsg;    private Object data;    /*getter  setter 省略*/}

定义statusCode == 0 为成功,则从data中获取数据,否则失败,从statusMsg中获取错误信息。
同时,对于请求url地址统一定位于/api/ 之下,这样既可通过url判断该请求属于视图还是API接口。

将返回的ModelAndView 改为Object,同时加上@ResponseBody 修改后的@ControllerAdvice如下

@ControllerAdvicepublic class ErrorView {    @ResponseBody    @ExceptionHandler(value=Exception.class)    public Object defaultErrorHandler(HttpServletRequest request, Exception e) throws Exception {        if (!returnJson(request)) {            ModelAndView view = new ModelAndView();            view.addObject("ERRORCODE", 500);            view.addObject("ERRORMSG", e.getMessage());            view.addObject("URL", request.getRequestURL());            view.setViewName("error");            return view;        } else {            System.out.println("is json");            ResultBean bean = new ResultBean();            bean.setReturnCode(-1);            bean.setReturnMsg("[api异常]" + e.getMessage());            return bean;                }    }       @ResponseBody    @ExceptionHandler(value=NoHandlerFoundException.class)    public Object pageNoFoundHandler(HttpServletRequest request, Exception e) throws Exception {        if (!returnJson(request)) {            ModelAndView view = new ModelAndView();            view.addObject("ERRORCODE", 404);            view.addObject("ERRORMSG", "页面未找到");            view.addObject("URL", request.getRequestURL());            view.setViewName("error");            return view;        } else {            System.out.println("is json");            ResultBean bean = new ResultBean();            bean.setReturnCode(-1);            bean.setReturnMsg("地址未找到");            return bean;        }    }    private boolean returnJson(HttpServletRequest request){        System.out.println(request.getRequestURI());        return request.getRequestURI().contains("/api/");    }}

这样在调用Api出现异常时既可返回相应的错误信息。效果入下:
这里写图片描述

这里写图片描述

0 0
原创粉丝点击