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
を指定し、JSON
をMap
に変換するだけですか?
編集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]
以前に述べたように、エラーメッセージは、application/octet-stream
をContent-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-Type
がapplication/json
であり、クラスパスにジャクソン1または2がある場合、RestTemplate
はJSONを逆シリアル化して、Java.util.Map
にうまく変換できます。
表示されていないエラーで、デフォルトのオブジェクトを上書きするカスタムHttpMessageConverter
オブジェクトを登録したか、クラスパスにJacksonがなく、MappingJackson2HttpMessageConverter
がありませんt登録済み(逆シリアル化を行う)またはapplication/json
を受け取っていません。
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)
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;
RestTemplateを使用し、応答タイプとしてJsonNodeを指定するだけで、目的の目的を達成できると思います。
ResponseEntity<JsonNode> response =
restTemplate.exchange(url, HttpMethod.GET, entity, JsonNode.class);
JsonNode map = response.getBody();
String someValue = map.get("someValue").asText();
私はその古いことを知っていますが、このトピックを訪れる可能性のある他の人のためだけに: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;
}