Spring Bootのヘッダー操作を徹底解説!Location・Retry-After・CORSの設定方法まとめ
生徒
「先生、Spring BootでHTTPレスポンスのヘッダーを自由に設定するにはどうすればいいですか?」
先生
「良い質問ですね。LocationヘッダーやRetry-After、そしてCORS関連ヘッダーも、Spring Bootで柔軟に制御できますよ。」
生徒
「Locationってリダイレクトのとき使うやつですか?Retry-Afterは聞いたことないです…」
先生
「そのとおり。では、ヘッダー操作の基本から、Spring Bootでの実装例まで一緒に確認していきましょう!」
1. Spring BootでHTTPレスポンスヘッダーを操作する基本
Spring Bootでは、ResponseEntityやHttpServletResponseを使ってレスポンスヘッダーを自由に操作できます。HTTPヘッダーは、APIの動作を制御したり、ブラウザやクライアントに指示を出すための重要な要素です。
たとえば、リダイレクト先の指定にはLocationヘッダー、再試行を促すにはRetry-Afterヘッダー、セキュリティやCORS制御にはAccess-Control-Allow-Originなどが使われます。
2. Locationヘッダーの設定方法と用途
Locationヘッダーは、HTTPステータスコード201 Createdや3xx Redirect系のレスポンスで、クライアントに遷移先のURLを伝える際に使用されます。
以下は、ResponseEntityでLocationヘッダーを付与する例です。
@PostMapping("/users")
public ResponseEntity<Void> createUser() {
URI location = URI.create("/users/123");
return ResponseEntity.created(location).build();
}
created(location)を使うことで、201 CreatedとLocationヘッダーを自動で設定してくれます。
3. Retry-Afterヘッダーの使い方と実装
Retry-Afterヘッダーは、リクエストを受け入れられない状態で、クライアントに「何秒後に再試行してほしいか」を伝えるために使われます。ステータスコード503 Service Unavailableや429 Too Many Requestsとセットで利用されることが多いです。
@GetMapping("/maintenance")
public ResponseEntity<String> maintenance() {
HttpHeaders headers = new HttpHeaders();
headers.add("Retry-After", "120"); // 120秒後に再試行
return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE)
.headers(headers)
.body("メンテナンス中です。しばらくしてから再度アクセスしてください。");
}
このようにすることで、アクセス集中時やメンテナンス中の丁寧な対応が可能になります。
4. CORS関連ヘッダー(Access-Control-Allow-*)の設定方法
CORS(クロスオリジンリソースシェアリング)に対応するためには、いくつかのHTTPレスポンスヘッダーを設定する必要があります。代表的なヘッダーは以下の通りです。
Access-Control-Allow-OriginAccess-Control-Allow-MethodsAccess-Control-Allow-Headers
Spring Bootでは、次のようにしてこれらを個別に付与することも可能です。
@GetMapping("/cors-data")
public ResponseEntity<String> corsData() {
HttpHeaders headers = new HttpHeaders();
headers.add("Access-Control-Allow-Origin", "*");
headers.add("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
headers.add("Access-Control-Allow-Headers", "Content-Type, Authorization");
return ResponseEntity.ok().headers(headers).body("CORS対応のデータ");
}
このように明示的に設定すれば、フロントエンドとの連携時のエラー回避にも役立ちます。
5. グローバルにCORS設定を適用する方法(セキュリティ向け)
個別にCORSヘッダーを付ける方法に加えて、グローバルに全体へ適用する方法もあります。これはWebMvcConfigurerを使って実装します。
@Configuration
public class CorsGlobalConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("*");
}
}
この設定により、すべてのAPIエンドポイントでCORSが有効になり、ヘッダーも一括で付与されます。
6. HttpServletResponseを使った手動ヘッダー追加の方法
コントローラー内でHttpServletResponseを直接使えば、細かな制御も可能です。以下はRetry-Afterを手動で設定する例です。
@GetMapping("/retry-manual")
public void retryManual(HttpServletResponse response) throws IOException {
response.setStatus(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
response.setHeader("Retry-After", "60");
response.getWriter().write("手動でヘッダーを追加した例です。");
}
細かくヘッダー制御したい場合や、Springの抽象化を使わずに記述したいときに便利な方法です。
7. セキュリティとパフォーマンスの観点でのヘッダー設計
ヘッダー操作は便利な反面、セキュリティやパフォーマンスにも影響を与えるため注意が必要です。たとえば以下のような配慮が求められます。
- Access-Control-Allow-Originに
*を指定する場合は、認証が不要なAPIのみに限定する - Locationヘッダーでリダイレクト先を動的に指定する際は、オープンリダイレクトの脆弱性に注意する
- Retry-Afterは適切な再試行時間を設定し、ユーザー体験と負荷分散を両立させる