resttemplate getForObject map responsetype

Zac*_*ber 16 java spring json resttemplate

更新02/05/2018(大约4年后)...我再次对此进行了测试,因为人们一直在讨论我的问题/答案,Sotirios Delimanolis是正确的,我不应该在我的答案中编写代码来完成这项工作.我使用了基本相同的RestTemplate/REST服务设置,如我的问题所示,REST服务具有确认的响应内容类型application/json,RestTemplate能够处理响应而没有问题进入Map.


我正在调用一个JSON像这样返回的休息服务:

{
   "some.key" : "some value",
   "another.key" : "another value"
}
Run Code Online (Sandbox Code Playgroud)

我想我可以使用java.util.Map响应类型来调用此服务,但这对我不起作用.我得到这个例外:

org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [interface java.util.Map]
Run Code Online (Sandbox Code Playgroud)

我应该只指定String为响应类型并将其转换JSONMap

编辑我

这是我的restTemplate调用:

private Map<String, String> getBuildInfo(String buildUrl) {
    return restTemplate.getForObject(buildUrl, Map.class);
}
Run Code Online (Sandbox Code Playgroud)

这是我如何设置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);
}
Run Code Online (Sandbox Code Playgroud)

编辑二

完整的错误消息:

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]
Run Code Online (Sandbox Code Playgroud)

Sot*_*lis 12

正如我在前面所指出的,你的错误信息向我们展示您收到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]
Run Code Online (Sandbox Code Playgroud)

因此,杰克逊MappingJackson2HttpMessageConverter无法解析内容(它的预期application/json).


原始答案:

假设您的HTTP响应Content-Type是,application/json并且您在类路径上有Jackson 1或2,那么RestTemplate可以像您一样将JSON反序列化为java.util.Map正常.

你得到的错误,你没有完整显示,你要么注册了自定义HttpMessageConverter对象,要么覆盖默认对象,要么你的类路径中没有杰克逊,而且MappingJackson2HttpMessageConverter没有注册(这将是反序列化)或者你没有收到application/json.


Jer*_*myW 11

RestTemplate有一个名为exchange的方法,它将ParameterizedTypeReference的一个实例作为参数.

java.util.Map创建返回a的GET请求,只需创建一个继承自ParameterizedTypeReference的匿名类的实例.

ParameterizedTypeReference<HashMap<String, String>> responseType = 
               new ParameterizedTypeReference<HashMap<String, String>>() {};
Run Code Online (Sandbox Code Playgroud)

然后,您可以调用exchange方法:

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

  • 效果很好。交换方法能够处理 ParameterizedTypeReference。 (2认同)

Zac*_*ber 8

更新02/05/2018(大约4年后)...我再次对此进行了测试,因为人们一直在讨论我的问题/答案,Sotirios Delimanolis是正确的,我不应该在我的答案中编写代码来完成这项工作.我使用了基本相同的RestTemplate/REST服务设置,如我的问题所示,REST服务具有确认的响应内容类型application/json,RestTemplate能够处理响应而没有问题进入Map.


我最终得到的内容为a 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;
Run Code Online (Sandbox Code Playgroud)

  • 这是多余的,不必要的.你正在创建和使用一个`ObjectMapper`几乎就像`RestTemplate`已经应该做的那样. (7认同)

小智 5

我认为您只需使用RestTemplate并指定JsonNode作为响应类型即可实现您的目标。

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

    JsonNode map = response.getBody();

    String someValue = map.get("someValue").asText();
Run Code Online (Sandbox Code Playgroud)

  • 接下来,您将需要:[更快的XML Jackson:删除双引号](/sf/ask/2005260071/) (2认同)