Spring RestTemplateでのHTTP 400エラー原因と解決方法

問題の概要

Spring FrameworkのRestTemplateを使用してHTTPリクエストを行う際、org.springframework.web.client.HttpClientErrorException: 400例外が発生することがあります。このエラーはHTTPステータスコード400(Bad Request)を示しており、クライアントからのリクエストがサーバーで正しく処理できない状態を表します。

主な原因

  • リクエストボディの形式エラーまたは必須情報の欠落
  • 不正なURL形式またはパラメータ不足
  • リクエストヘッダーの設定不備
  • API仕様との不一致

検証と解決アプローチ

1. API仕様の確認

使用するAPIの公式ドキュメントを精査し、以下の要素が仕様通りであることを確認します:

  • エンドポイントURLとHTTPメソッド
  • 必須パラメータとオプションパラメータ
  • 期待されるリクエストボディ形式(JSON/XMLなど)
  • 必要な認証情報とヘッダー設定

2. リクエストボディの検証

JSON形式のリクエストを送信する場合、以下の方法で形式を検証します:

import org.json.JSONObject;
import org.json.JSONException;

public boolean isValidJson(String jsonString) {
    try {
        new JSONObject(jsonString);
        return true;
    } catch (JSONException e) {
        return false;
    }
}

3. URLとパラメータの構築

URLの構築にはUriComponentsBuilderを使用し、安全なURL生成を実現します:

import org.springframework.web.util.UriComponentsBuilder;

String apiUrl = UriComponentsBuilder
    .fromHttpUrl("https://api.example.com/users")
    .queryParam("page", 1)
    .queryParam("limit", 10)
    .encode()
    .toUriString();

4. ヘッダー設定の最適化

必要なヘッダーを明示的に設定します:

import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;

HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setContentType(MediaType.APPLICATION_JSON);
requestHeaders.setBearerAuth("your-access-token");
requestHeaders.set("X-Custom-Header", "custom-value");

実装例

完全な実装例を示します:

import org.springframework.web.client.RestTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.ResponseEntity;

public class ApiClient {
    private final RestTemplate restTemplate;
    
    public ApiClient() {
        this.restTemplate = new RestTemplate();
    }
    
    public String executePostRequest(String url, String requestBody, 
                                   HttpHeaders headers) {
        HttpEntity<String> requestEntity = new HttpEntity<>(requestBody, headers);
        
        try {
            ResponseEntity<String> response = restTemplate.postForEntity(
                url, requestEntity, String.class);
            return response.getBody();
        } catch (HttpClientErrorException e) {
            System.err.println("Error response: " + e.getResponseBodyAsString());
            throw e;
        }
    }
}

デバッグ手法

  • サーバー側のエラーレスポンスを詳細に確認
  • リクエスト内容をログ出力して検証
  • ネットワークツールを使用した実際のリクエスト/レスポンスの確認
  • ステージング環境でのテスト実施

タグ: Spring Framework RestTemplate HTTP 400 Java API Integration

7月24日 01:27 投稿