resttemplate getForObject map responsetype
更新02/05/2018(大约4年后)…我再次对此进行了测试,因为人们一直在讨论我的问题/答案,Sotirios Delimanolis是正确的,我不应该在我的答案中编写代码来完成这项工作。 我使用了基本相同的RestTemplate / REST服务设置,如我的问题所示,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
吗?
编辑我
这是我的restTemplate调用:
private Map getBuildInfo(String buildUrl) { return restTemplate.getForObject(buildUrl, Map.class); }
这是我如何设置restTemplate:
@PostConstruct public void initialize() { List 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); }
编辑二
完整的错误消息:
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]
因此,Jackson的MappingJackson2HttpMessageConverter
无法解析内容(它正在期待application/json
)。
原始答案:
假设你的HTTP响应的Content-Type
是application/json
并且你在类路径上有Jackson 1或者2,那么RestTemplate
可以像你一样将JSON反序列化为java.util.Map
就好了。
你得到的错误,你没有完整显示,你要么注册了自定义的HttpMessageConverter
对象,这些对象会覆盖默认值,或者你的类路径上没有Jackson,而且没有注册MappingJackson2HttpMessageConverter
(这会做反序列化)或者你没有收到application/json
。
RestTemplate有一个名为exchange的方法,它将ParameterizedTypeReference的一个实例作为参数。
要创建一个返回java.util.Map
的GET请求,只需创建一个inheritance自ParameterizedTypeReference的匿名类的实例。
ParameterizedTypeReference> responseType = new ParameterizedTypeReference>() {};
然后,您可以调用exchange方法:
RequestEntity request = RequestEntity.get(URI("http://example.com/foo")) .accept(MediaType.APPLICATION_JSON).build() Map jsonDictionary = restTemplate.exchange(request, responseType)
更新02/05/2018(大约4年后)…我再次对此进行了测试,因为人们一直在讨论我的问题/答案,Sotirios Delimanolis是正确的,我不应该在我的答案中编写代码来完成这项工作。 我使用了基本相同的RestTemplate / REST服务设置,如我的问题所示,REST服务具有已确认的响应内容类型application / json,RestTemplate能够处理响应而没有问题进入Map。
我最终得到的内容为String
,然后将它们转换为这样的Map
:
String json = restTemplate.getForObject(buildUrl, String.class); Map map = new HashMap(); ObjectMapper mapper = new ObjectMapper(); try { //convert JSON string to Map map = mapper.readValue(json, new TypeReference>(){}); } catch (Exception e) { logger.info("Exception converting {} to map", json, e); } return map;
我认为你可以实现你的目标,只需使用RestTemplate并指定一个JsonNode作为响应类型。
ResponseEntity 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; }