resttemplate getForObject map responsetype

后端 未结 6 1741
囚心锁ツ
囚心锁ツ 2021-02-06 23:58

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 h

相关标签:
6条回答
  • 2021-02-07 00:21

    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();
    
    0 讨论(0)
  • 2021-02-07 00:30

    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;
    
    0 讨论(0)
  • 2021-02-07 00:32
    @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 ...

    0 讨论(0)
  • 2021-02-07 00:35

    RestTemplate has a method named exchange that takes an instance of ParameterizedTypeReference 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<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)
    
    0 讨论(0)
  • 2021-02-07 00:36

    As I had previously noted, your error message is showing us that you are receiving application/octet-stream as a 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, 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.

    0 讨论(0)
  • 2021-02-07 00:36

    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;
    }
    
    0 讨论(0)
提交回复
热议问题