ResponseEntity為單獨介面實現靈活返回值控制

  • 2019 年 12 月 20 日
  • 筆記

Restful API的Web後台服務,一般都提供了統一的介面規範。但是有時候又需要提供回調地址給外部服務,比如微信支付。那麼這個回調介面的返回值需要滿足微信支付回調的返回值協議(這個協議跟項目的Web後台服務不一致)。 利用ResponseEntity可以單獨為某個介面實現返回值的完全控制,也不用修改項目的整體協議規範。

實現

  • 項目的統一返回值協議WebResult
/**   * @author timxia   * @since 2019/8/13   */  @Getter  @Setter  @ToString  @NoArgsConstructor  public class WebResult<T> {      private static final int SUCCESS_CODE = 200;      private static final int SERVER_ERROR_CODE = 500;        private static final String SUCCESS_MSG = "操作成功";      private static final String ERROR_SERVER = "伺服器繁忙,請稍後再試";        public static final WebResult<Void> SUCCESS_RESULT = new WebResult<>();      public static final WebResult<Void> SERVER_ERROR_RESULT = new WebResult<>(SERVER_ERROR_CODE, ERROR_SERVER);        /**       * 錯誤碼.       */      private int code = SUCCESS_CODE;        /**       * 錯誤資訊.       */      private String msg = SUCCESS_MSG;        /**       * 結果內容.       */      private T data;        public WebResult(int code, String msg) {          this.code = code;          this.msg = msg;      }        public WebResult(T data) {          this.data = data;      }  }
  • 返回不同的HttpStatus
@RequestMapping("home")  @RestController  @SpringBootApplication  public class BootEntityApplication {        public static void main(String[] args) {          SpringApplication.run(BootEntityApplication.class, args);      }        @GetMapping("ping")      public WebResult<Void> ping() {          return WebResult.SUCCESS_RESULT;      }        /**       * 根據不同的異常情況,配置不同的HttpStatus       */      @GetMapping("exception")      public ResponseEntity<WebResult> exception(int ex) {          try {              doWork(ex);              return ResponseEntity.ok(WebResult.SUCCESS_RESULT);          } catch (IllegalArgumentException e) {              //不同的異常設置不同的HttpStatus              return ResponseEntity.status(HttpStatus.BAD_REQUEST)                      .body(new WebResult<>(400, e.getMessage()));          } catch (RuntimeException e) {              return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)                      .body(WebResult.SERVER_ERROR_RESULT);          }      }        private void doWork(int ex) {          switch (ex) {              case 0:                  return;              case 1:                  throw new IllegalArgumentException("bad request");              default:                  throw new RuntimeException("伺服器繁忙");          }      }  }

測試

# 沒有異常HttpStatus=200  $ curl -i -X GET 'http://localhost:8080/home/exception?ex=0'    HTTP/1.1 200  Content-Type: application/json  Transfer-Encoding: chunked  Date: Tue, 17 Dec 2019 13:29:55 GMT    {"code":200,"msg":"操作成功","data":null,"success":true}    #參數異常HttpStatus=400  $ curl -i -X GET 'http://localhost:8080/home/exception?ex=1'    HTTP/1.1 400  Content-Type: application/json  Transfer-Encoding: chunked  Date: Tue, 17 Dec 2019 13:29:19 GMT  Connection: close    {"code":400,"msg":"bad request","data":null,"success":false}    #伺服器異常HttpStatus=500  $ curl -i -X GET 'http://localhost:8080/home/exception?ex=2'    HTTP/1.1 500  Content-Type: application/json  Transfer-Encoding: chunked  Date: Tue, 17 Dec 2019 13:30:05 GMT  Connection: close    {"code":500,"msg":"伺服器繁忙,請稍後再試","data":null,"success":false}

優點

  • 使用ResponseEntity可以針對單個介面實現靈活的返回值控制,包括HttpStatus
  • 如果在所有介面實現對某一個異常都設置統一的HttpStatus,可以使用ExceptionHandler
  • 使用HttpServletResponse也可以實現非常靈活的返回值控制,但是太底層了,不夠面向對象,不建議使用