【问题标题】:How to parse jsonObject and JsonArray for the same field in REST Response如何为 REST 响应中的同一字段解析 jsonObject 和 JsonArray
【发布时间】:2018-07-13 07:18:55
【问题描述】:

我使用 RestTemplate 调用了一个 api,假设 /getCompany

通常响应如下:-

"Organization":{
  "name": "My Company",
  "department": {
     "id": "1",
     "employee": [{
       "id": "84",
       "name": "abc"
      },
      {
       "id": "85",
       "name": "xyz"
      }]
 }
}

所以我将其解析如下:-

ResponseEntity<Organization> company= new RestTemplate().exchange(new URI(companyUrl),HttpMethod.GET,request, Organization.class);
Organization comp= company.getBody();
Department dept= comp.getDepartment();
Employee[] emp = dept.getEmployees()

但有时在响应中我也会得到以下 json 字符串:

"Organization":{
  "name": "My Company",
  "department": {
     "id": "1",
     "employee": {
       "id": "84",
       "name": "abc"
      }     
   }
}

现在我得到以下异常:-

Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of Employee[] out of START_OBJECT token

那么有什么办法可以处理这两种情况吗?

更新:-

根据评论添加以下代码:-

@Bean
public ObjectMapper getObjectMapper() {
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
    return objectMapper;
}

@Bean
public MappingJackson2HttpMessageConverter mappingJacksonHttpMessageConverter(ObjectMapper objectMapper) {
    MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
    converter.setObjectMapper(objectMapper);
    return converter;
}

但仍然遇到同样的异常。

谢谢,

【问题讨论】:

    标签: json rest deserialization resttemplate


    【解决方案1】:

    注册的objectMapper必须配合ACCEPT_SINGLE_VALUE_AS_ARRAY参数使用。

    也许实现这一目标的最简单方法是在带有@Configuration 注释的类中注册正确初始化的ObjectMapperMappingJacksonHttpMessageConverter

    @Bean
    public ObjectMapper getObjectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.enable(ACCEPT_SINGLE_VALUE_AS_ARRAY);
        return objectMapper;
    }
    
    @Bean
    public MappingJacksonHttpMessageConverter mappingJacksonHttpMessageConverter(ObjectMapper objectMapper) {
        MappingJacksonHttpMessageConverter converter = new MappingJacksonHttpMessageConverter();
        converter.setObjectMapper(objectMapper);
        return converter;
    }
    

    另一种方法是直接将转换器设置为restTemplate对象:

    public ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.enable(ACCEPT_SINGLE_VALUE_AS_ARRAY);
        return objectMapper;
    }
    
    
    public MappingJackson2HttpMessageConverter httpConverter(ObjectMapper objectMapper) {
        return new MappingJackson2HttpMessageConverter(objectMapper);
    }
    
    public void restTemplate() {
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.setMessageConverters(Arrays.asList(httpConverter(objectMapper())));
        restTemplate.exchange(...);
    }
    

    【讨论】:

    • 如何在我的 restTemplate 调用中使用它?你能提供任何示例链接吗?
    • 只需在你的上下文中的@Configuration 类中注册这些bean,你的restTemplate 就会使用它们。
    • 但在部门 json 中还有其他单个 json 值不应被视为数组。那么你提供的代码会影响他们吗?更新了我的 jsonString
    • 所以不会添加 objectMapper.enable(ACCEPT_SINGLE_VALUE_AS_ARRAY);会影响我的 getDepartment,因为 Department 应该是单个对象。它将单个部门对象视为数组吗?
    • “它会将单个部门对象视为数组吗?”-> 不,此选项仅在您的 java 类声明数组并且传入的 json 字段只是一个对象时才有帮助
    【解决方案2】:

    JSON 是一种 javascript 对象表示法。 JSON 与 javascript 的语法相同。在 JSON 中,数组值的类型必须是字符串、数组、数字、布尔对象或 null。

    【讨论】:

      猜你喜欢
      • 2014-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-12
      相关资源
      最近更新 更多