web-dev-qa-db-ja.com

resttemplate getForObjectマップresponsetype

Update 02/05/2018(約4年後)...人々が私の質問/回答を支持しており、Sotirios Delimanolisはすべきではないのでこれを再度テストしましたこの作業を行うには、答えにコードを書く必要があります。基本的に、REST確認された応答コンテンツタイプがapplication/jsonとRestTemplateは問題なく応答をMapに処理できました。


次のようなJSONを返すRESTサービスを呼び出しています。

{
   "some.key" : "some value",
   "another.key" : "another value"
}

Java.util.Mapを応答タイプとしてこのサービスを呼び出すことができると思いますが、それは私にとってはうまくいきません。私はこの例外を受け取ります:

org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [interface Java.util.Map]

応答タイプとしてStringを指定し、JSONMapに変換するだけですか?

編集I

ここに私のrestTemplate呼び出しがあります:

private Map<String, String> getBuildInfo(String buildUrl) {
    return restTemplate.getForObject(buildUrl, Map.class);
}

RestTemplateの設定方法は次のとおりです。

@PostConstruct
public void initialize() {
    List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
    interceptors.add(new ClientHttpRequestInterceptor() {
        @Override
        public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
            HttpRequestWrapper requestWrapper = new HttpRequestWrapper(request);
            requestWrapper.getHeaders().setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
            return execution.execute(requestWrapper, body);
        }
    });
    restTemplate.setInterceptors(interceptors);
}

編集II

完全なエラーメッセージ:

org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [interface Java.util.Map] and content type [application/octet-stream]
    at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.Java:108) ~[spring-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.Java:549) ~[spring-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.Java:502) ~[spring-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
    at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.Java:239) ~[spring-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
    at idexx.ordering.services.AwsServersServiceImpl.getBuildInfo(AwsServersServiceImpl.Java:96) ~[classes/:na]
16
Zack Macomber

以前に述べたように、エラーメッセージは、application/octet-streamContent-Typeとして受け取っていることを示しています。

org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [interface Java.util.Map] and content type [application/octet-stream]

そのため、ジャクソンのMappingJackson2HttpMessageConverterはコンテンツを解析できません(application/jsonが必要です)。


元の回答:

HTTP応答のContent-Typeapplication/jsonであり、クラスパスにジャクソン1または2がある場合、RestTemplateはJSONを逆シリアル化して、Java.util.Mapにうまく変換できます。

表示されていないエラーで、デフォルトのオブジェクトを上書きするカスタムHttpMessageConverterオブジェクトを登録したか、クラスパスにJacksonがなく、MappingJackson2HttpMessageConverterがありませんt登録済み(逆シリアル化を行う)またはapplication/jsonを受け取っていません。

12

RestTemplateにはというメソッドがあります exchangeパラメーターとしてParameterizedTypeReferenceのインスタンスを取ります。

Java.util.Mapを返すGETリクエストを作成するには、ParameterizedTypeReferenceを継承する匿名クラスのインスタンスを作成するだけです。

ParameterizedTypeReference<HashMap<String, String>> responseType = 
               new ParameterizedTypeReference<HashMap<String, String>>() {};

その後、交換メソッドを呼び出すことができます。

RequestEntity<Void> request = RequestEntity.get(URI("http://example.com/foo"))
                 .accept(MediaType.APPLICATION_JSON).build()
Map<String, String> jsonDictionary = restTemplate.exchange(request, responseType)
11
JeremyW

Update 02/05/2018(約4年後)...人々が私の質問/回答を支持しており、Sotirios Delimanolisはすべきではないのでこれを再度テストしましたこの作業を行うには、答えにコードを書く必要があります。基本的に、REST確認された応答コンテンツタイプがapplication/jsonとRestTemplateは問題なく応答をMapに処理できました。


内容をStringとして取得し、次のようにMapに変換しました。

String json = restTemplate.getForObject(buildUrl, String.class);
Map<String,String> map = new HashMap<String,String>();
ObjectMapper mapper = new ObjectMapper();

try {
    //convert JSON string to Map
   map = mapper.readValue(json, new TypeReference<HashMap<String,String>>(){});
} catch (Exception e) {
     logger.info("Exception converting {} to map", json, e);
}

return map;
8
Zack Macomber

RestTemplateを使用し、応答タイプとしてJsonNodeを指定するだけで、目的の目的を達成できると思います。

    ResponseEntity<JsonNode> response = 
         restTemplate.exchange(url, HttpMethod.GET, entity, JsonNode.class);

    JsonNode map = response.getBody();

    String someValue = map.get("someValue").asText();
4

私はその古いことを知っていますが、このトピックを訪れる可能性のある他の人のためだけに:RestTemplateBuilderでいくつかの追加のコンバーターを登録する場合は、デフォルトのコンバーターも明示的に登録する必要があります

@Bean
public RestTemplateBuilder builder() {
    return new RestTemplateBuilder()
            .defaultMessageConverters()
            .additionalMessageConverters(halMessageConverter());
}

private HttpMessageConverter halMessageConverter() {
    ObjectMapper objectMapper = new ObjectMapper().registerModule(new Jackson2HalModule());
    TypeConstrainedMappingJackson2HttpMessageConverter halConverter = new TypeConstrainedMappingJackson2HttpMessageConverter(ResourceSupport.class);
    halConverter.setSupportedMediaTypes(Collections.singletonList(MediaTypes.HAL_JSON));
    halConverter.setObjectMapper(objectMapper);
    return halConverter;
}
0
WrRaThY