網頁

2019/12/24

Spring Boot @ControllerAdvice return json response

在Spring Boot / Spring Web MVC的@ControllerAdvice類別處理錯誤時,如果要以json返回結果,可使用ResponseEntity<T>回傳。

改用@RestControllerAdvice即可,就不用自行撰寫ResponseEntity<T>的包裝邏輯。




本範例設定及內容請參考Spring Boot @ControllerAdvice用法


例如下面是自訂例外錯誤DemoException

DemoException

package com.abc.demo.exception;

public class DemoException extends RuntimeException {

    private String errorCode;
    private String errorMessage;

    public DemoException(String errorCode, String errorMessage) {
        this.errorCode = errorCode;
        this.errorMessage = errorMessage;
    }
    // getters and setters
}

下面為自訂的回應內容類別DemoResponse。此物件會放入ResponseEntity<T>的實例中成為Response body並轉換為json回傳出去。

DemoResponse

package com.abc.demo.controller.response;

public class DemoResponse {

    private String code;
    private String message;

    public DemoResponse(String code, String message) {
        this.code = code;
        this.message = message;
    }
    // getters and setters
}

下面的DemoExceptionHandler為掛有@ControllerAdvice的類別,用來處理DemoException

DemoExceptionHandler.handleDemoException()處理DemoException例外時產生DemoResponse物件,然後以此作為ResponseEntity(@Nullable T body, HttpStatus status)的參數來建構ResponseEntity<DemoResponse>物件。所以DemoResponse物件是Response body,最終會轉為json回傳。

由於這裏是返回應用程式發生錯誤時的結果,所以回應HTTP狀態碼500,也就是HttpStatus.INTERNAL_SERVER_ERROR

DemoExceptionHandler

package com.abc.demo.exception.handler;

import com.abc.demo.controller.response.DemoResponse;
import com.abc.demo.exception.DemoException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

@ControllerAdvice
public class DemoExceptionHandler {

    @ExceptionHandler({DemoException.class})
    public final ResponseEntity<DemoResponse> handleDemoException(DemoException ex) {
        DemoResponse response = new DemoResponse(ex.getErrorCode(), ex.getErrorMessage());
        return new ResponseEntity<>(response, HttpStatus.INTERNAL_SERVER_ERROR);
    }

}

下面是拋出錯誤的DemoController

DemoController

package com.abc.demo.controller;

import com.abc.demo.exception.DemoException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DemoController {

    @GetMapping("/hello")
    public String hello() {

        throw new DemoException("9999", "test");

    }

}

系統啟動後,在瀏覽器網址列輸入http://localhost:8080/demo/hello,返回結果如下。

{
    code: "9999", 
    message: "test"
}

可以看到json的結構即為DemoResponse的屬性。


沒有留言:

張貼留言