新建項目相關的類

新建 MyResponse,作為統一樣式 JSON 的實體類

public class MyResponse{
    private String status;
    private String message;
    // 省略 getter setter constructor
}

新建 User,傳入參數的檢驗

public class User {
    @NotEmpty(message = "用戶名不能為空")
    @Pattern(regexp = "^[a-zA-Z0-9]{3,16}$", message = "用戶名需3到16位的英文,數字")
    private String username;
    // 省略 getter setter constructor
}

新建 MyException,自定義異常

public class MyException  extends Throwable{
    private final String status;
    private final String  message;

    public MyException(String  status,String message) {
        this.status=status;
       this.message=message;
    }

    public String getStatus() {
        return status;
    }

    @Override
    public String getMessage() {
        return message;
    }
}

新建 ErrorController

@RestController
public class ErrorController {

    @RequestMapping("/throw")
    public String myThrow() throws MyException {
        // Throw MyException
        throw new MyException("Error", "Throw MyException");
    }

    @PostMapping("/user")
    public String user(@RequestBody @Valid final User user) {
        // 參數檢驗
        return "參數檢驗通過";
    }
}

運行項目,分別訪問不存在的路徑和上述路徑:例如用 Get 方法訪問 /user,會返回如下:

{
    "timestamp": "2020-04-16T16:43:41.123+0000",
    "status": 405,
    "error": "Method Not Allowed",
    "message": "Request method 'GET' not supported",
    "path": "/user"
}

添加全局異常處理,@RestControllerAdvice

新建 ErrorRestControllerAdvice

@RestControllerAdvice
public class ErrorRestControllerAdvice {
    /** 全局異常捕捉處理 返回 401 狀態 */
    @ExceptionHandler(value = Exception.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public MyResponse errorHandler(Exception ex) {
        return new MyResponse("ERROR", ex.getMessage());
    }

    /** 自定義異常捕獲,返回 500 狀態 */
    @ExceptionHandler(value = MyException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public MyResponse myException(MyException e) {
        return new MyResponse(e.getStatus(), e.getMessage());
    }

    /** Http Method 異常 返回 405 */
    @ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
    @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
    public MyResponse httpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
        return new MyResponse("ERROR", e.getMessage());
    }

    /** 404異常,返回 404 NOT_FOUND 異常 */
    @ExceptionHandler(value = NoHandlerFoundException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public MyResponse noHandlerFoundException(NoHandlerFoundException e) {
        return new MyResponse("ERROR", "資源不存在");
    }

    /** RequestBody 為空時返回此錯誤提醒,返回400 bad Request */
    @ExceptionHandler(value = HttpMessageNotReadableException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public MyResponse httpMessageNotReadableException() {
        return new MyResponse("ERROR", "請傳入參數");
    }

    /** RequestBody某個必須輸入的參數為空時 返回 400 Bad Request */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public MyResponse methodDtoNotValidException(Exception ex) {
        MethodArgumentNotValidException c = (MethodArgumentNotValidException) ex;
        List<ObjectError> errors = c.getBindingResult().getAllErrors();
        StringBuffer errorMsg = new StringBuffer();
        errors.forEach(x -> errorMsg.append(x.getDefaultMessage()).append(" "));
        return new MyResponse("ERROR", errorMsg.toString());
    }
}

代碼解析:

@RestControllerAdvice:等于 @ResponseBody + @ControllerAdvice@ControllerAdvice 是 Spring 增強的 Controller 控制器,用于定義@ExceptionHandler@InitBinder@ModelAttribute方法

@ExceptionHandler(value = Exception.class) : 是 將 value 捕獲到的異常交由其注解的方法處理。如果是注解在 @Controller 中,僅僅會當前類中生效,而注解在 @ControllerAdvice 則是全局有效的。

@ResponseStatus(HttpStatus.BAD_REQUEST) : 設置該異常的狀態返回碼。

重新運行項目,分別訪問不存在的路徑,?/throw,/user,觀察其前后的不同。例如通過 GET 訪問 /user,則會返回如下:

{
    "status": "ERROR",
    "message": "Request method 'GET' not supported"
}

Spring Boot 的微信登錄因為個人開發者無法申請,因此暫定不寫了。下一篇計劃是 Spring Boot 整合 Redis 緩存。

文章轉自微信公眾號@編程技術進階

上一篇:

強力監控!Spring Boot 3.3 集成 Zipkin 全面追蹤 RESTful API 性能

下一篇:

SpringBoot無侵入式實現接口統一返回JSON格式
#你可能也喜歡這些API文章!

我們有何不同?

API服務商零注冊

多API并行試用

數據驅動選型,提升決策效率

查看全部API→
??

熱門場景實測,選對API

#AI文本生成大模型API

對比大模型API的內容創意新穎性、情感共鳴力、商業轉化潛力

25個渠道
一鍵對比試用API 限時免費

#AI深度推理大模型API

對比大模型API的邏輯推理準確性、分析深度、可視化建議合理性

10個渠道
一鍵對比試用API 限時免費