筱进GG的gravatar头像
筱进GG2017-11-10 21:04:31
Spring Boot学习(六)之Web应用的统一异常处理

我们在做web项目中,都遇到了404,405,500这样的错误信息,需要需要处理异常信息,

启动该应用,访问一个不存在的URL,或是修改处理内容,直接抛出异常,如:

@RequestMapping("/hello")
public String hello() throws Exception {
    throw new Exception("发生错误");
}

Spring Boot中默认带了error的映射,但是这个错误页面显示给用户并不是很友好。

Spring Boot学习(六)之Web应用的统一异常处理

统一异常处理

虽然,Spring Boot中实现了默认的error映射,但是在实际应用中,上面你的错误页面对用户来说并不够友好,我们通常需要去实现我们自己的异常提示。

下面我们开始学习统一处理:

  • 创建全局异常处理类:通过使用@ControllerAdvice定义统一的异常处理类,而不是在每个Controller中逐个定义。@ExceptionHandler用来定义函数针对的异常类型,最后将Exception对象和请求URL映射到error.html中
import com.didispace.dto.ErrorInfo;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
/**
 * 筱进GG
 */
@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(value = Exception.class)
    public ModelAndView defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception {
        ModelAndView mav = new ModelAndView();
        mav.addObject("exception", e);
        mav.addObject("url", req.getRequestURL());
        mav.setViewName("error");
        return mav;
    }
}

  • 实现error.html页面展示:在templates目录下创建error.html,将请求的URL和Exception对象的message输出。
<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8" />
    <title>统一异常处理</title>
</head>
<body>
<h1>Error Handler</h1>
<div th:text="${url}"></div>
<div th:text="${exception.message}"></div>
</body>
</html>

启动该应用,访问:http://localhost:8080/hello,可以看到如下错误提示页面。

Spring Boot学习(六)之Web应用的统一异常处理

通过实现上述内容之后,我们只需要在Controller中抛出Exception,当然我们可能会有多种不同的Exception。然后在@ControllerAdvice类中,根据抛出的具体Exception类型匹配@ExceptionHandler中配置的异常类型来匹配错误映射和处理。

返回JSON格式

在上述例子中,通过@ControllerAdvice统一定义不同Exception映射到不同错误处理页面。而当我们要实现RESTful API时,返回的错误是JSON格式的数据,而不是HTML页面,这时候我们也能轻松支持。

本质上,只需在@ExceptionHandler之后加入@ResponseBody,就能让处理函数return的内容转换为JSON格式。

下面以一个具体示例来实现返回JSON格式的异常处理。

  • 创建统一的JSON返回对象,code:消息类型,message:消息内容,url:请求的url,data:请求返回的数据
/**
 * 筱进GG
 */
public class ErrorInfo<T> {

    public static final Integer OK = 0;
    public static final Integer ERROR = 100;

    private Integer code;
    private String message;
    private String url;
    private T data;

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public static Integer getOK() {
        return OK;
    }

    public static Integer getERROR() {
        return ERROR;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }
    
}
  • 创建一个自定义异常,用来实验捕获该异常,并返回json
/**
 * 筱进GG
 */
public class MyException extends Exception {

    public MyException(String message) {
        super(message);
    }

}
  • Controller中增加json映射,抛出MyException异常
 @RequestMapping("/json")
    public String json() throws MyException {
        throw new MyException("发生错误2");
    }
  • 为MyException异常创建对应的处理
  @ExceptionHandler(value = MyException.class)
    @ResponseBody
    public ErrorInfo<String> jsonErrorHandler(HttpServletRequest req, MyException e) throws Exception {
        ErrorInfo<String> r = new ErrorInfo<>();
        r.setMessage(e.getMessage());
        r.setCode(ErrorInfo.ERROR);
        r.setData("Some Data");
        r.setUrl(req.getRequestURL().toString());
        return r;
    }

启动应用,访问:http://localhost:8080/json ,可返回如下内容:

{
    code: 100,
    data: "Some Data",
    message: "发生错误2",
    url: "http://localhost:8080/json"
}

到此我们完成了统一异常处理,欢迎学习交流,

祝大家双十一购物快乐!!


打赏

已有1人打赏

最代码官方的gravatar头像

分享到:

最近浏览
406971727昨天
最代码贡献等级说明
ITfans前天
最代码贡献等级说明
bzyaocom前天
最代码贡献等级说明
newlife199111月15日
暂无贡献等级
xjc62110511月15日
暂无贡献等级
aihui52311月15日
最代码贡献等级说明
yoummde11月15日
暂无贡献等级
smjjjjsm11月15日
暂无贡献等级
weienqing11月15日
最代码贡献等级说明
Tandaly LV311月14日
最代码贡献等级说明
俏飘佳人11月14日
最代码贡献等级说明
喜你人多11月14日
暂无贡献等级
小王wang11月13日
最代码贡献等级说明
junwuxie11月13日
最代码贡献等级说明
程序猿全敏 LV311月13日
最代码贡献等级说明
Watson11月13日
最代码贡献等级说明
perfect11月13日
最代码贡献等级说明
wkshitc11月13日
最代码贡献等级说明
顶部客服微信二维码底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友