0Day Forums
resttemplate getForObject map responsetype - Printable Version

+- 0Day Forums (https://zeroday.vip)
+-- Forum: Coding (https://zeroday.vip/Forum-Coding)
+--- Forum: FrameWork (https://zeroday.vip/Forum-FrameWork)
+---- Forum: Spring (https://zeroday.vip/Forum-Spring)
+---- Thread: resttemplate getForObject map responsetype (/Thread-resttemplate-getForObject-map-responsetype)



resttemplate getForObject map responsetype - cyr670 - 08-02-2023

***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.***

----------

I'm invoking a rest service that returns `JSON` like this:

{
"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:

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`?

<b>Edit I</b>

Here's my restTemplate call:

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

Here's how I'm setting up the 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);
}

<b>Edit II</b>

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]




RE: resttemplate getForObject map responsetype - kerrilljjy - 08-02-2023

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

@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;
}


RE: resttemplate getForObject map responsetype - mindimindless629 - 08-02-2023

As I had previously noted, your error message is showing us that you are receiving `application/octet-stream` as a `Content-Type`.

<!-- language:none -->

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, Jackson's `MappingJackson2HttpMessageConverter` cannot parse the content (it's expecting `application/json`).


----------


Original answer:

Assuming your HTTP response's `Content-Type` is `application/json` and you have have Jackson 1 or 2 on the classpath, a `RestTemplate` can deserialize JSON like you have into a `java.util.Map` just fine.

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 Jackson on your classpath and the `MappingJackson2HttpMessageConverter` isn't registered (which would do the deserialization) or you aren't receiving `application/json`.



RE: resttemplate getForObject map responsetype - lithochromatics399060 - 08-02-2023

I think you can achieve what you're aiming for simply using the RestTemplate and specifying a JsonNode as the response type.

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

JsonNode map = response.getBody();

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




RE: resttemplate getForObject map responsetype - digraph315 - 08-02-2023

***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.***

----------

I ended up getting the contents as a `String` and then converting them to a `Map` like this:

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;


RE: resttemplate getForObject map responsetype - foxtrot690 - 08-02-2023

@GetMapping(value = "getSunny/{userId}")
public Map<String, SunnyVO> getSunny(@PathVariable int sunnyId) {

Map<String, SunnyVO> newObj = new HashMap<String, SunnyVO>();
final String url = "http://localhost:8085/Sunny/getSunny/{sunnyId}";
RestTemplate restTemplate = new RestTemplate();
newObj = restTemplate.getForObject(url, Map.class, sunnyId);
return newObj;

}

It is working for me ...


RE: resttemplate getForObject map responsetype - semillons890188 - 08-02-2023

This worked 100% for me

in client

Map<String, Object> mapRespuesta = new HashMap<>();
mapRespuesta.put("mensaje", "Process completed successfully");
mapRespuesta.put("idResponse", id);
return new ResponseEntity<Map<String, Object>>(mapRespuesta, HttpStatus.OK);

in which it makes the connection

ResponseEntity<Map> result = restTemplate.postForEntity(url, params, Map.class);
String id = result.getBody().get("idResponse").toString();


RE: resttemplate getForObject map responsetype - neognathaezfx - 08-02-2023

**RestTemplate** has a method named **[exchange][1]** that takes an instance of **[ParameterizedTypeReference][2]** as parameter.

To make a GET request that returns a `java.util.Map`, just create an instance of an anonym class that inherits from ParameterizedTypeReference.

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

You can then invoke the exchange method:

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


[1]:

[To see links please register here]

-
[2]:

[To see links please register here]