web-dev-qa-db-ja.com

カスタムヘッダーを使用したResttemplateGETリクエスト

ヘッダー付きのGETリクエストを送信する必要があります:Content-Type: application/camiant-msr-v2.0+xml。サーバーからのXML応答を期待しています。 Postmanでリクエストとレスポンスをテストしましたが、すべて問題ありません。しかし、SpringでRestTemplateを使用してそれを実行しようとすると、常に400の不正な要求が発生します。 springの例外は次のとおりです。

Jul 09, 2016 12:53:38 PM org.Apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [dispatcherServlet] in context with path [/smp] threw exception [Request processing failed; nested exception is org.springframework.web.client.HttpClientErrorException: 400 Bad Request] with root cause
org.springframework.web.client.HttpClientErrorException: 400 Bad Request
    at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.Java:91)
    at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.Java:641)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.Java:597)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.Java:557)
    at org.springframework.web.client.RestTemplate.exchange(RestTemplate.Java:475)

私のコード:

MultiValueMap<String, String> headers = new LinkedMultiValueMap<String, String>();
headers.add("Content-Type", "application/camiant-msr-v2.0+xml");

HttpEntity<?> entity = new HttpEntity<Object>(headers);
log.debug("request headers: " + entity.getHeaders());
ResponseEntity<String> response = restTemplate.exchange(queryUrl, HttpMethod.GET, entity, String.class);

デバッグメッセージには、ヘッダーが{Content-Type=[application/camiant-msr-v2.0+xml]}として表示されますが、これは正しいようです。リクエストの何が問題になっているのか、デバッグするためにネットワーク上のリクエストを確認する方法があるのだろうか。

5
J Freebird

実際には、渡されるヘッダーはGETメソッドであるため、Content-TypeではなくAcceptという名前にする必要があります。しかし、サーバーAPIドキュメントはどういうわけかContent-Typeを期待していると言っており、コマンドライン/ PostmanからのAPIはContent-TypeAcceptの両方でうまく機能しました。 Content-TypeヘッダーがGETリクエストに渡されるのを防ぐのはJavaライブラリだと思います。

1
J Freebird

以下は私のために働いた:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

@Service
public class Http {

    @Autowired
    private RestTemplate restTemplate;

    public String doGet(final String url) throws Exception {
        MultiValueMap<String, String> headers = new LinkedMultiValueMap<String, String>();
        headers.add(HttpHeaders.USER_AGENT, "Mozilla/5.0");
        headers.add(HttpHeaders.ACCEPT_LANGUAGE, "en-US,en;q=0.8");
        HttpEntity<?> entity = new HttpEntity<Object>(headers);
        HttpEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);
        return response.getBody();
    }

}
3

400の考えられる解釈は、コンテンツタイプがリクエストに受け入れられないか、URLが一致しないことです。

私の個人的な経験から、あなたがqueryUrlを台無しにしていると強く感じているので、ここで物事を微調整するには、SpringのUriComponentsBuilderクラスを使用することをお勧めします。

UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url)
        .queryParam("data", data);

HttpEntity<?> entity = new HttpEntity<>(headers);

HttpEntity<String> response = restTemplate.exchange(
        builder.build().encode().toUri(), 
        HttpMethod.GET, 
        entity, 
        String.class);

それでも機能しない場合はお知らせください。

1
Mudassar