1. ホーム
  2. Java

API の戻り値を処理するために ResponseEntity を使用する

2022-02-13 12:13:38
<パス

最近、Google AMP メールをやっていて、/unsub (配信停止) インターフェースを呼び出すときに特定の ResponseHeader を google クライアントに返す必要がある問題に遭遇した。しかし、プロジェクトでは Springboot 2.x を使用しており、通常 @RestController で API レイヤーを変更するので、動的に特定の Header を返せなかったのである。だから、どのようにいくつかの特別な戻り値のカプセル化を行うには、特別なAPIを行うには?Spring framework ResponseEntityクラスは、この問題を解決するための良い方法です。

ご存知のように、私たちのHTTP/HTTPSレスポンスは、ステータスコード、ヘッダー情報、レスポンスボディの内容の3つの主要なブロックで構成されており、一連の戻り値でラップして結果を返すことができますが、ステータスコードとヘッダー情報については特別な設定が必要です。

ResponseEntityの使用

まずは、ResponseEntityが実際にどのように使われているのか、ソースコードから見ていきましょう。

1. ResponseEntityの最初の使われ方

public class ResponseEntity
 extends HttpEntity
 {
    public ResponseEntity(HttpStatus status) {
	    this((Object)null, (MultiValueMap)null, (HttpStatus)status);
	}
	
   public ResponseEntity(@Nullable T body, HttpStatus status) {
        this(body, (MultiValueMap)null, (HttpStatus)status);
    }
	
   public ResponseEntity(MultiValueMap
You can see that this class provides five constructor methods, the returned status code is mandatory, the header information and the response body content are optional. When we need to use it, we can just new a ResponseEntity object as the API return value, which is the first way it can be used.
Note that in the constructor method with headers as a parameter, you need to pass in a parameter of type MultiValueMap<String, String>. MultiValueMap inherits from the abstract class Map, which has a subclass called HttpHeaders, which we can use as a HttpHeaders holds the key values of some common Header, such as "Accept-Charset". Of course you can also customize some special keys.
HttpHeaders headers = new HttpHeaders();
headers.add("Access-Control-Expose-Headers", "AMP-Access-Control-Allow-Source-Origin");

return new ResponseEntity<>(resultBody, headers, HttpStatus.OK);

2. The second way to use ResponseEntity
Continuing to look at the source code, I found a lot of methods that return a value of ResponseEntity.
    public static ResponseEntity.BodyBuilder status(HttpStatus status) {
        Assert.notNull(status, "HttpStatus must not be null");
        Return new ResponseEntity.DefaultBuilder(status);
    }

    public static ResponseEntity.BodyBuilder status(int status) {
        DefaultBuilder(status);
    }
        public static ResponseEntity.BodyBuilder ok() {
        return status(HttpStatus.OK);
    }
    public static ResponseEntity.BodyBuilder created(URI location) {
        ResponseEntity.BodyBuilder builder = status(HttpStatus.CREATED);
        BodyBuilder return (ResponseEntity.BodyBuilder)builder.location(location);
    }

    public static ResponseEntity.BodyBuilder accepted() {
        return status(HttpStatus.ACCEPTED);
    }

    public static ResponseEntity.HeadersBuilder<? > noContent() {
        return status(HttpStatus.NO_CONTENT);
    }

    public static ResponseEntity.BodyBuilder badRequest() {
        return status(HttpStatus.BAD_REQUEST);
    }

    public static ResponseEntity.HeadersBuilder<? > notFound() {
        return status(HttpStatus.NOT_FOUND);
    }

    public static ResponseEntity.BodyBuilder unprocessableEntity() {
        return status(HttpStatus.UNPROCESSABLE_ENTITY);
    }
    .........

It turns out that the greater the software engineer, the "lazier" he is. To save time and increase efficiency, we can use the Builder approach to generate the ResponseEntity object and return.
Map
Comparison with other methods
The @RestController annotation modifies the controller layer.
@RestController = @Controller + @ResponseBody

The @ResponseBody is the object returned by the controller's method that is written to the body area of the response object after being converted to the specified format by the appropriate converter, usually used to return JSON data or XML data.
Note: After using this annotation the view handler (ModelAndView) does not go any further, but writes the data directly to the input stream, which has the same effect as outputting the specified format of data through the response object. @ResponseStatus This annotation is mainly used on custom Exceptions, or directly on API methods in the controller layer, and returns the corresponding Http status code and msg when an exception occurs/method execution ends. @ResponseStatus(value=HttpStatus.FORBIDDEN,reason="Access not allowed") Notes.
ResponseEntity has higher priority than @ResponseBody; only check for @ResponseBody annotations if the return value is not ResponseEntity; if the response type is ResponseEntity the @ResponseBody annotation is ignored. Summary ResponseEntity makes it very easy to modify the status code of the return value, but the best use is still the ability to set different return response headers for different APIs.
HttpHeaders headers = new HttpHeaders(); headers.add("Access-Control-Expose-Headers", "AMP-Access-Control-Allow-Source-Origin"); return new ResponseEntity<>(resultBody, headers, HttpStatus.OK);