Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java resttemplate getForObject映射响应类型_Java_Json_Spring_Resttemplate - Fatal编程技术网

Java resttemplate getForObject映射响应类型

Java resttemplate getForObject映射响应类型,java,json,spring,resttemplate,Java,Json,Spring,Resttemplate,2018年5月2日更新(大约4年后)…我再次测试了这一点,因为人们对我的问题/答案进行了投票,Sotirios Delimanolis认为我不必在我的答案中编写代码来实现这一点是正确的。我使用了与我的问题中所示基本相同的RestTemplate/REST服务设置,REST服务的确认响应内容类型为application/json,并且RestTemplate能够在地图中处理响应,没有任何问题。 我正在调用一个返回JSON的rest服务,如下所示: { "some.key" : "some

2018年5月2日更新(大约4年后)…我再次测试了这一点,因为人们对我的问题/答案进行了投票,Sotirios Delimanolis认为我不必在我的答案中编写代码来实现这一点是正确的。我使用了与我的问题中所示基本相同的RestTemplate/REST服务设置,REST服务的确认响应内容类型为application/json,并且RestTemplate能够在地图中处理响应,没有任何问题。


我正在调用一个返回
JSON
的rest服务,如下所示:

{
   "some.key" : "some value",
   "another.key" : "another value"
}
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;
我想我可以用
java.util.Map
作为响应类型来调用这个服务,但这对我不起作用。我得到一个例外:

org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [interface java.util.Map]
我是否应该指定
String
作为响应类型,并将
JSON
转换为
Map

编辑一

这是我的restTemplate调用:

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

正如我之前提到的,您的错误消息向我们显示,您正在以
内容类型
的形式接收
应用程序/octet流

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]
因此,Jackson的
映射Jackson2HttpMessageConverter
无法解析内容(它需要
应用程序/json


原始答复:

假设HTTP响应的
内容类型
application/json
,并且类路径上有Jackson 1或Jackson 2,那么
RestTemplate
可以像反序列化到
java.util.Map
中一样反序列化json

对于您得到的错误,您没有完整显示,或者您注册了覆盖默认值的自定义
HttpMessageConverter
对象,或者您的类路径上没有Jackson,并且没有注册
MappingJackson2HttpMessageConverter
(这将进行反序列化)或者您没有收到2018年5月2日更新的
应用程序/json

(大约4年后)…我再次测试了这一点,因为人们一直在对我的问题/答案进行投票,Sotirios Delimanolis是正确的,我不应该在我的答案中编写代码来实现这一点。我使用了与我的问题中所示基本相同的RestTemplate/REST服务设置,REST服务的确认响应内容类型为application/json,并且RestTemplate能够在地图中处理响应,没有任何问题。


我最终将内容作为
字符串
获取,然后将其转换为
映射
,如下所示:

{
   "some.key" : "some value",
   "another.key" : "another value"
}
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;
String json=restemplate.getForObject(buildUrl,String.class);
Map Map=newhashmap();
ObjectMapper mapper=新的ObjectMapper();
试一试{
//将JSON字符串转换为映射
map=mapper.readValue(json,newTypeReference(){});
}捕获(例外e){
info(“将{}转换为映射的异常”,json,e);
}
返回图;

我知道它很古老,但只针对可能访问此主题的其他人: 如果您想用RestTemplateBuilder注册一些额外的转换器,您还必须显式注册默认转换器

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

restemplate有一个名为的方法,该方法将的实例作为参数

要发出返回
java.util.Map
的GET请求,只需创建从ParameterizedTypeReference继承的匿名类的实例

ParameterizedTypeReference<HashMap<String, String>> responseType = 
               new ParameterizedTypeReference<HashMap<String, String>>() {};
ParameteredTypeReference响应类型=
新的ParameteredTypeReference(){};
然后可以调用exchange方法:

RequestEntity<Void> request = RequestEntity.get(URI("http://example.com/foo"))
                 .accept(MediaType.APPLICATION_JSON).build()
Map<String, String> jsonDictionary = restTemplate.exchange(request, responseType)
RequestEntity request=RequestEntity.get(URI(“http://example.com/foo"))
.accept(MediaType.APPLICATION_JSON).build()
Map jsonDictionary=restTemplate.exchange(请求,响应类型)

我认为,只要使用RestTemplate并将JsonNode指定为响应类型,就可以实现您的目标

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

    JsonNode map = response.getBody();

    String someValue = map.get("someValue").asText();
ResponseEntity响应=
exchange(url,HttpMethod.GET,entity,JsonNode.class);
JsonNode map=response.getBody();
字符串someValue=map.get(“someValue”).asText();
@GetMapping(value=“getSunny/{userId}”)
公共地图getSunny(@PathVariable int sunnyId){
Map newObj=newhashmap();
最终字符串url=”http://localhost:8085/Sunny/getSunny/{sunnyId}”;
RestTemplate RestTemplate=新RestTemplate();
newObj=restemplate.getForObject(url,Map.class,sunnyId);
返回newObj;
}

它对我有效…

在密钥名称中有点有效吗?我想这会有点让人困惑。@EngineerDollery它是JSON,很好。你能告诉我们如何创建和使用你的
RestTemplate
?@SotiriosDelimanolis——它是JSON,所以是有效的,但仍然不好。如果您想将其转换为javascript对象,然后使用点表示法访问该对象,您将有点为难。@EngineerDollery我很确定javascript足够聪明来处理这个问题。在任何情况下,错误消息都与键的值无关。这是多余和不必要的。您正在创建和使用一个
ObjectMapper
,这与
RestTemplate
应该做的几乎一模一样。这不应该是公认的答案,您不需要编写代码就可以做到这一点@道格:我接受了自己的答案,因为它对我有用。我发现很多时候我只需要完成工作,继续前进。我还没有测试Sotirios Delimanolis的答案,但我怀疑他是正确的。@ZackMacomber请发布完整的stacktrace和完整的错误消息。oops-忘记发布了…现在就把它放在那里了。@ZackMacomber从错误消息中可以看出,响应的
内容类型
没有设置为
application/json
。这就是你需要改变的。如果你的API没有返回它,就像你对请求所做的那样注入它。只是澄清一下,这意味着你可以这样做:ResponseEntityAllo,还有一件事要检查,因为我就要输了
@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;

    }