Update 02/05/2018 (ca. 4 Jahre später) ... Ich habe das noch einmal getestet, da die Leute meine Frage/Antwort auf den neuesten Stand gebracht haben und Sotirios Delimanolis richtig ist, dass ich den Code in meiner Antwort nicht schreiben muss mach das klappen Ich habe im Wesentlichen das gleiche RestTemplate/REST-Service-Setup verwendet, das in meiner Frage mit dem REST -Dienst mit einem bestätigten Antwort-Inhaltstyp/json angegeben ist, und RestTemplate konnte die Antwort ohne Probleme in eine Map verarbeiten.
Ich rufe einen Ruhedienst auf, der JSON
wie folgt zurückgibt:
{
"some.key" : "some value",
"another.key" : "another value"
}
Ich würde gerne glauben, dass ich diesen Service mit einem Java.util.Map
als Antworttyp aufrufen kann, aber das funktioniert nicht für mich. Ich bekomme diese Ausnahme:
org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [interface Java.util.Map]
Soll ich nur String
als Antworttyp angeben und die JSON
in eine Map
umwandeln?
Editiere ich
Hier ist mein restTemplate-Aufruf:
private Map<String, String> getBuildInfo(String buildUrl) {
return restTemplate.getForObject(buildUrl, Map.class);
}
So richten Sie die restTemplate ein:
@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);
}
Bearbeiten II
Vollständige Fehlermeldung:
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]
Wie bereits erwähnt, zeigt Ihre Fehlermeldung an, dass Sie application/octet-stream
als Content-Type
empfangen.
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]
Daher kann Jacksons MappingJackson2HttpMessageConverter
den Inhalt nicht analysieren (er erwartet application/json
).
Ursprüngliche Antwort:
Wenn Sie davon ausgehen, dass Content-Type
Ihrer HTTP-Antwort application/json
ist und Sie über Jackson 1 oder 2 im Klassenpfad verfügen, kann eine RestTemplate
JSON wie in einem Java.util.Map
deserialisieren.
Bei dem Fehler, den Sie nicht vollständig angezeigt haben, haben Sie entweder benutzerdefinierte HttpMessageConverter
-Objekte registriert, die die Standardwerte überschreiben, oder Sie haben Jackson nicht in Ihrem Klassenpfad, und der MappingJackson2HttpMessageConverter
ist nicht registriert (was der Fall wäre.) Deserialisierung durchführen) oder Sie erhalten application/json
nicht.
RestTemplate hat eine Methode namens exchange, die eine Instanz von ParameterizedTypeReference als Parameter verwendet.
Erstellen Sie zum Erstellen einer GET-Anforderung, die einen Java.util.Map
zurückgibt, eine Instanz einer anonymen Klasse, die von ParameterizedTypeReference erbt.
ParameterizedTypeReference<HashMap<String, String>> responseType =
new ParameterizedTypeReference<HashMap<String, String>>() {};
Sie können dann die Austauschmethode aufrufen:
RequestEntity<Void> request = RequestEntity.get(URI("http://example.com/foo"))
.accept(MediaType.APPLICATION_JSON).build()
Map<String, String> jsonDictionary = restTemplate.exchange(request, responseType)
Update 02/05/2018 (ca. 4 Jahre später) ... Ich habe das noch einmal getestet, da die Leute meine Frage/Antwort auf den neuesten Stand gebracht haben und Sotirios Delimanolis richtig ist, dass ich den Code in meiner Antwort nicht schreiben muss mach das klappen Ich habe im Wesentlichen das gleiche RestTemplate/REST-Service-Setup verwendet, das in meiner Frage mit dem REST -Dienst mit einem bestätigten Antwort-Inhaltstyp/json angegeben ist, und RestTemplate konnte die Antwort ohne Probleme in eine Map verarbeiten.
Am Ende bekam ich die Inhalte als String
und konvertierte sie dann in eine Map
wie folgt:
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;
Ich denke, Sie können erreichen, was Sie erreichen möchten, indem Sie einfach das RestTemplate verwenden und einen JsonNode als Antworttyp angeben.
ResponseEntity<JsonNode> response =
restTemplate.exchange(url, HttpMethod.GET, entity, JsonNode.class);
JsonNode map = response.getBody();
String someValue = map.get("someValue").asText();
Ich weiß, dass es alt ist, aber nur für andere Personen, die dieses Thema besuchen: Wenn Sie zusätzliche Konverter bei RestTemplateBuilder registrieren möchten, müssen Sie auch die Standardkonvertierungen explizit registrieren
@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;
}