Java resttemplate getForObject 映射响应类型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24208828/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
resttemplate getForObject map responsetype
提问by Zack Macomber
Update 02/05/2018 (about 4 years later)...I tested this again as people have been upvoting my question/answer and Sotirios Delimanolis is correct that I should not have to write the code in my answer to make this work. I used basically the same RestTemplate/REST service setup as shown in my question with the REST service having a confirmed response content type of application/json and RestTemplate was able to process the response with no issues into a Map.
2018 年 2 月 5 日更新(大约 4 年后)......我再次测试了这一点,因为人们一直在支持我的问题/答案,Sotirios Delimanolis 是正确的,我不应该在我的答案中编写代码来完成这项工作。我使用了基本相同的 RestTemplate/REST 服务设置,如我的问题中所示,REST 服务具有应用程序/json 的确认响应内容类型,并且 RestTemplate 能够毫无问题地将响应处理到 Map 中。
I'm invoking a rest service that returns JSON
like this:
我正在调用一个返回JSON
这样的休息服务:
{
"some.key" : "some value",
"another.key" : "another value"
}
I would like to think that I can invoke this service with a java.util.Map
as the response type but that's not working for me. I get this exception:
我想我可以使用 ajava.util.Map
作为响应类型来调用此服务,但这对我不起作用。我得到这个例外:
org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [interface java.util.Map]
Should I just specify String
as the response type and convert the JSON
to a Map
?
我应该只指定String
为响应类型并将 the 转换JSON
为 aMap
吗?
Edit I
编辑我
Here's my restTemplate call:
这是我的 restTemplate 电话:
private Map<String, String> getBuildInfo(String buildUrl) {
return restTemplate.getForObject(buildUrl, Map.class);
}
Here's how I'm setting up the restTemplate:
这是我设置 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);
}
Edit II
编辑二
Full error message:
完整的错误信息:
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]
采纳答案by Sotirios Delimanolis
As I had previously noted, your error message is showing us that you are receiving application/octet-stream
as a Content-Type
.
正如我之前所指出的,您的错误消息向我们表明您收到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]
As such, Hymanson's MappingHymanson2HttpMessageConverter
cannot parse the content (it's expecting application/json
).
因此,Hyman逊MappingHymanson2HttpMessageConverter
无法解析内容(期待application/json
)。
Original answer:
原答案:
Assuming your HTTP response's Content-Type
is application/json
and you have have Hymanson 1 or 2 on the classpath, a RestTemplate
can deserialize JSON like you have into a java.util.Map
just fine.
假设您的 HTTP 响应Content-Type
是application/json
并且您在类路径上有 Hymanson 1 或 2,则RestTemplate
可以像您一样将 JSON 反序列化为一个java.util.Map
就好了。
With the error you are getting, which you haven't shown in full, either you've registered custom HttpMessageConverter
objects which overwrite the defaults ones, or you don't have Hymanson on your classpath and the MappingHymanson2HttpMessageConverter
isn't registered (which would do the deserialization) or you aren't receiving application/json
.
对于您收到的错误,您没有完整显示,要么您注册了HttpMessageConverter
覆盖默认对象的自定义对象,要么您的类路径上没有 Hymanson 并且MappingHymanson2HttpMessageConverter
未注册(这将执行反序列化)或者您没有收到application/json
.
回答by Zack Macomber
Update 02/05/2018 (about 4 years later)...I tested this again as people have been upvoting my question/answer and Sotirios Delimanolis is correct that I should not have to write the code in my answer to make this work. I used basically the same RestTemplate/REST service setup as shown in my question with the REST service having a confirmed response content type of application/json and RestTemplate was able to process the response with no issues into a Map.
2018 年 2 月 5 日更新(大约 4 年后)......我再次测试了这一点,因为人们一直在支持我的问题/答案,Sotirios Delimanolis 是正确的,我不应该在我的答案中编写代码来完成这项工作。我使用了基本相同的 RestTemplate/REST 服务设置,如我的问题中所示,REST 服务具有应用程序/json 的确认响应内容类型,并且 RestTemplate 能够毫无问题地将响应处理到 Map 中。
I ended up getting the contents as a String
and then converting them to a Map
like this:
我最终将内容作为 aString
然后将它们转换为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;
回答by WrRaThY
I know its old, but just for other people that may visit this topic: If you want to register some additional converters with RestTemplateBuilder you also have to explicitly register default ones
我知道它是旧的,但仅适用于可能访问此主题的其他人:如果您想使用 RestTemplateBuilder 注册一些额外的转换器,您还必须明确注册默认的
@Bean
public RestTemplateBuilder builder() {
return new RestTemplateBuilder()
.defaultMessageConverters()
.additionalMessageConverters(halMessageConverter());
}
private HttpMessageConverter halMessageConverter() {
ObjectMapper objectMapper = new ObjectMapper().registerModule(new Hymanson2HalModule());
TypeConstrainedMappingHymanson2HttpMessageConverter halConverter = new TypeConstrainedMappingHymanson2HttpMessageConverter(ResourceSupport.class);
halConverter.setSupportedMediaTypes(Collections.singletonList(MediaTypes.HAL_JSON));
halConverter.setObjectMapper(objectMapper);
return halConverter;
}
回答by JeremyW
RestTemplatehas a method named exchangethat takes an instance of ParameterizedTypeReferenceas parameter.
RestTemplate有一个名为exchange的方法,它将ParameterizedTypeReference的实例作为参数。
To make a GET request that returns a java.util.Map
, just create an instance of an anonym class that inherits from ParameterizedTypeReference.
要发出返回 a 的 GET 请求java.util.Map
,只需创建一个从 ParameterizedTypeReference 继承的匿名类的实例。
ParameterizedTypeReference<HashMap<String, String>> responseType =
new ParameterizedTypeReference<HashMap<String, String>>() {};
You can then invoke the exchange method:
然后您可以调用交换方法:
RequestEntity<Void> request = RequestEntity.get(URI("http://example.com/foo"))
.accept(MediaType.APPLICATION_JSON).build()
Map<String, String> jsonDictionary = restTemplate.exchange(request, responseType)
回答by riversidetraveler
I think you can achieve what you're aiming for simply using the RestTemplate and specifying a JsonNode as the response type.
我认为您只需使用 RestTemplate 并指定 JsonNode 作为响应类型即可实现您的目标。
ResponseEntity<JsonNode> response =
restTemplate.exchange(url, HttpMethod.GET, entity, JsonNode.class);
JsonNode map = response.getBody();
String someValue = map.get("someValue").asText();