1. 程式人生 > >Spring Boot中Web應用的統一異常處理實戰

Spring Boot中Web應用的統一異常處理實戰

 一 建立全域性異常處理類

package com.didispace.exception;

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;
//通過使用@ControllerAdvice定義統一的異常處理類,而不是在每個Controller中逐個定義。
@ControllerAdvice
public class GlobalExceptionHandler {
    //@ExceptionHandler用來定義函式針對的異常型別
    @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());
        //將Exception物件和請求URL對映到error.html中
        mav.setViewName("error");
        return mav;
    }
    //@ExceptionHandler用來定義函式針對的異常型別
    @ExceptionHandler(value = MyException.class)
    //在@ExceptionHandler之後加入@ResponseBody,就能讓處理函式return的內容轉換為JSON格式。
    @ResponseBody
    public ErrorInfo<String> jsonErrorHandler(HttpServletRequest req, MyException e) throws Exception {
        //為MyException異常建立對應的處理
        ErrorInfo<String> r = new ErrorInfo<>();
        r.setMessage(e.getMessage());
        r.setCode(ErrorInfo.ERROR);
        r.setData("Some Data");
        r.setUrl(req.getRequestURL().toString());
        return r;
    }

}

二 顯示錯誤展示模板

<!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>

三 新增pom

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
</dependencies>

四 新建控制器

package com.didispace.web;

import com.didispace.exception.MyException;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/*
在Controller中丟擲Exception,當然我們可能會有多種不同的Exception。然後在@ControllerAdvice類中,根據丟擲的具體Exception型別匹配@ExceptionHandler中配置的異常型別來匹配錯誤對映和處理。
*/
@Controller
public class HelloController {

    @RequestMapping("/hello")
    public String hello() throws Exception {
        throw new Exception("發生錯誤");
    }

    //丟擲MyException異常
    @RequestMapping("/json")
    public String json() throws MyException {
        throw new MyException("發生錯誤2");
    }
}

五 建立錯誤資訊類

/*
建立統一的JSON返回物件
*/
package com.didispace.dto;

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;  //請求的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
*/
public class MyException extends Exception {

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

七 測試

1 測試Exception

瀏覽器輸入:http://localhost:8080/hello

2 測試MyException

瀏覽器輸入:http://localhost:8080/json