Spring ResponseEntityを使用してHTTP応答を操作する
1. 前書き
通常、Springを使用すると、HTTP応答の微調整など、同じ目標を達成するための多くの方法があります。
この短いチュートリアルでは、ResponseEntityを使用してHTTP応答の本文、ステータス、およびヘッダーを設定する方法を説明します。
参考文献:
Spring @ResponseStatusを使用してHTTPステータスコードを設定する
@ResponseStatusアノテーションと、それを使用して応答ステータスコードを設定する方法をご覧ください。
2. ResponseEntity
ResponseEntityrepresents the whole HTTP response: status code, headers, and body。 そのため、これを使用してHTTP応答を完全に構成できます。
使用する場合は、エンドポイントから返す必要があります。残りは春になります。
ResponseEntityはジェネリック型です。 その結果、任意のタイプを応答本文として使用できます。
@GetMapping("/hello")
ResponseEntity hello() {
return new ResponseEntity<>("Hello World!", HttpStatus.OK);
}
プログラムで応答ステータスを指定するため、さまざまなシナリオに応じてさまざまなステータスコードを返すことができます。
@GetMapping("/age")
ResponseEntity age(
@RequestParam("yearOfBirth") int yearOfBirth) {
if (isInFuture(yearOfBirth)) {
return new ResponseEntity<>(
"Year of birth cannot be in the future",
HttpStatus.BAD_REQUEST);
}
return new ResponseEntity<>(
"Your age is " + calculateAge(yearOfBirth),
HttpStatus.OK);
}
さらに、HTTPヘッダーを設定できます。
@GetMapping("/customHeader")
ResponseEntity customHeader() {
HttpHeaders headers = new HttpHeaders();
headers.add("Custom-Header", "foo");
return new ResponseEntity<>(
"Custom header set", headers, HttpStatus.OK);
}
さらに、ResponseEntityprovides two nested builder interfaces:HeadersBuilderとそのサブインターフェイスBodyBuilder。 したがって、ResponseEntityの静的メソッドを介してそれらの機能にアクセスできます。
最も単純なケースは、本文とHTTP 200応答コードを含む応答です。
@GetMapping("/hello")
ResponseEntity hello() {
return ResponseEntity.ok("Hello World!");
}
最も一般的なHTTPステータスコードについては、静的メソッドを取得します。
BodyBuilder accepted();
BodyBuilder badRequest();
BodyBuilder created(java.net.URI location);
HeadersBuilder> noContent();
HeadersBuilder> notFound();
BodyBuilder ok();
さらに、BodyBuilder status(HttpStatus status)メソッドとBodyBuilder status(int status)メソッドを使用して、任意のHTTPステータスを設定できます。
最後に、ResponseEntity<T> BodyBuilder.body(T body)を使用して、HTTP応答本文を設定できます。
@GetMapping("/age")
ResponseEntity age(@RequestParam("yearOfBirth") int yearOfBirth) {
if (isInFuture(yearOfBirth)) {
return ResponseEntity.badRequest()
.body("Year of birth cannot be in the future");
}
return ResponseEntity.status(HttpStatus.OK)
.body("Your age is " + calculateAge(yearOfBirth));
}
カスタムヘッダーを設定することもできます。
@GetMapping("/customHeader")
ResponseEntity customHeader() {
return ResponseEntity.ok()
.header("Custom-Header", "foo")
.body("Custom header set");
}
したがって、BodyBuilder.body()はBodyBuilder,ではなくResponseEntityを返します。これが最後の呼び出しである必要があります。
HeaderBuilderでは、応答本文のプロパティを設定できないことに注意してください。
コントローラからResponseEntity<T>オブジェクトを返すときに、リクエストの処理中に例外またはエラーが発生する可能性があり、return error-related information to the user represented as some other type let’s say Eを実行したいと考えています。
Spring 3.2は、グローバルな@ExceptionHandler with the new @ControllerAdvice annotationのサポートをもたらし、この種のシナリオを処理します。 詳細については、既存の記事hereを参照してください。
While ResponseEntity is very powerful, we shouldn’t overuse it.単純なケースでは、私たちのニーズを満たす他のオプションがあり、それらははるかにクリーンなコードになります。
3. 代替案
3.1. @ResponseBody
従来のSpring MVCアプリケーションでは、エンドポイントは通常、レンダリングされたHTMLページを返します。 たとえば、AJAXでエンドポイントを使用する場合など、実際のデータのみを返す必要がある場合があります。
このような場合、リクエストハンドラメソッドを@ResponseBodyおよびSpring treats the result value of the method as the HTTP response body自体でマークできます。
詳細については、this article is a good place to startを参照してください。
3.2. @ResponseStatus
エンドポイントが正常に戻ると、SpringはHTTP 200(OK)応答を提供します。 エンドポイントが例外をスローした場合、Springは使用するHTTPステータスを伝える例外ハンドラーを探します。
これらのメソッドは@ResponseStatusでマークできます。 したがって、Springreturns with a custom HTTP status。
その他の例については、custom status codesに関する記事をご覧ください。
3.3. 応答を直接操作する
Springでは、javax.servlet.http.HttpServletResponseオブジェクトに直接アクセスすることもできます。メソッド引数として宣言するだけです。
@GetMapping("/manual")
void manual(HttpServletResponse response) throws IOException {
response.setHeader("Custom-Header", "foo");
response.setStatus(200);
response.getWriter().println("Hello World!");
}
Springは、基礎となる実装であるwe shouldn’t manipulate the response this wayの上に抽象化と追加機能を提供します。
4. 結論
この記事では、SpringでHTTP応答を操作するための利点と欠点を備えた複数の方法を説明しました。
いつものように、例は利用可能なover on GitHubです。