【问题标题】:Unable to Map JSON to Java bean无法将 JSON 映射到 Java bean
【发布时间】:2015-03-09 13:11:11
【问题描述】:

我收到错误:

Exception in thread "main" org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Can not deserialize instance of com.zee.FilterVO out of START_ARRAY token. at [Source: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@1b54362; line: 1, column: 1]; nested exception is org.codehaus.jackson.map.JsonMappingException: : Can not deserialize instance of com.zee.FilterVO out of START_ARRAY token

获取 JSON 的 Java 调用:

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

Java Bean 映射 JSON:

public class FilterVO {

    private String userName;
    private String expirationTime;
    private String lastMatchedTime;
    private String state;
    private Integer matchedTodayCount;
    private Boolean useRegEx;
    private List<String> matchStrings;
    private List<String> hosts;
    private String activationTime;
    private String objectId;
    private String description;
    public Map<String, String> nameValuePairs;

    getters and setters....
}

JSON 我想得到什么:

[{
    "userName": "Z111111",
    "expirationTime": "2015-03-15T14:00:00.000-0400",
    "activationTime": "1969-12-31T19:00:00.000-0500",
    "hosts": ["aa", "bb"],
    "matchStrings": [" aa is not running", " bb is not running"],
    "useRegEx": false,
    "nameValuePairs": {
        "KEY VALUE": "asasa",
        "PROGRAM": "dsds",
        "REGION": "dfsffs"
    },
    "objectId": "SOMEID:20141015140803579-802",
    "matchedTodayCount": 190,
    "lastMatchedTime": "2015-03-09T07:53:20.366-0400",
    "state": "ACTIVE",
    "description": "Blah Blah Blah..."
}]

最初我认为我面临这个问题是因为一个元素数组的反序列化。所以我修改了我的java代码。

private void getFilter() {
        RestTemplate restTemplate = getCustomRestTemplate();
        HttpHeaders headers = new HttpHeaders();
        headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
        headers.set("access-token", getAccessToken());
        HttpEntity<String> entity = new HttpEntity<String>("parameters", headers);
        ResponseEntity<FilterVO> responseEntity = restTemplate.exchange(uri, HttpMethod.GET, entity, FilterVO.class);
}

private RestTemplate getCustomRestTemplate() {
        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(DeserializationConfig.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);     
        MappingJacksonHttpMessageConverter messageConverter = new MappingJacksonHttpMessageConverter();
        messageConverter.setObjectMapper(mapper);
        List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
        messageConverters.add(messageConverter);
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.setMessageConverters(messageConverters);
        return restTemplate;
}

我仍然遇到同样的错误。

我的类路径中有以下jackson jar:

jackson-annotations-2.5.1.jar
jackson-core-2.5.1.jar
jackson-core-asl-1.9.13.jar
jackson-databind-2.5.1.jar
jackson-datatype-joda-2.5.1.jar
jackson-mapper-asl-1.9.13.jar

完整堆栈跟踪:

Exception in thread "main" org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Can not deserialize instance of com.zee.FilterVO out of START_ARRAY token
 at [Source: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@bc5596; line: 1, column: 1]; nested exception is org.codehaus.jackson.map.JsonMappingException: Can not deserialize instance of com.zee.FilterVO out of START_ARRAY token
 at [Source: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@bc5596; line: 1, column: 1]
    at org.springframework.http.converter.json.MappingJacksonHttpMessageConverter.readJavaType(MappingJacksonHttpMessageConverter.java:179)
    at org.springframework.http.converter.json.MappingJacksonHttpMessageConverter.read(MappingJacksonHttpMessageConverter.java:171)
    at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:94)
    at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:693)
    at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:679)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:496)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:465)
    at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:416)
    at com.fidelity.selfservice.test.JMagicRestAPI.getFilter(JMagicRestAPI.java:63)
    at com.fidelity.selfservice.test.JMagicRestAPI.main(JMagicRestAPI.java:46)
Caused by: org.codehaus.jackson.map.JsonMappingException: Can not deserialize instance of com.zee.FilterVO out of START_ARRAY token
 at [Source: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@bc5596; line: 1, column: 1]
    at org.codehaus.jackson.map.JsonMappingException.from(JsonMappingException.java:163)
    at org.codehaus.jackson.map.deser.StdDeserializationContext.mappingException(StdDeserializationContext.java:219)
    at org.codehaus.jackson.map.deser.StdDeserializationContext.mappingException(StdDeserializationContext.java:212)
    at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromArray(BeanDeserializer.java:875)
    at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:597)
    at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.java:2732)
    at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1923)
    at org.springframework.http.converter.json.MappingJacksonHttpMessageConverter.readJavaType(MappingJacksonHttpMessageConverter.java:176)
    ... 9 more

【问题讨论】:

  • 地图怎么样,如果你删除它,它会起作用吗?
  • 删除了Map,还是一样的错误
  • 您的restTemplate.exchange 方法是否正确读取了完整的响应?服务器是否在响应处理周期结束时刷新整个响应?
  • 交换方法工作正常。如果我使用字符串,我会获取数据,即ResponseEntity&lt;String&gt; responseEntity = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);
  • @MarvinEmilBrach Full Stack Trace

标签: java json spring jackson resttemplate


【解决方案1】:

问题是您正在获取一个 JSON 数组,但您正尝试使用 POJO 反序列化该 JSON,在您的情况下为 FilterVO

尝试更改此行:

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

这个:

ResponseEntity<List<FilterVO>> responseEntity = 
    restTemplate.exchange(url, HttpMethod.GET, entity, 
    new ParameterizedTypeReference<List<FilterVO>>() {});

现在您可以使用 List&lt;FilterVO&gt;

【讨论】:

  • 他解析的发布的JSON不是数组,但可能是复制粘贴失败;我们会看到:)
  • @MarvinEmilBrach 当然,但堆栈跟踪表明正在发回一个数组。
  • @MarvinEmilBrach 我正在获取 JSON 数组。错过了方括号。 :(
  • 比 Magnamag 找到了答案。不要忘记接受并投票;)
  • @Magnamag TypeReference 不适用于 spring exchange 方法,而是我使用了 ParameterizedTypeReference。现在它工作正常。 :)
猜你喜欢
  • 2011-08-05
  • 1970-01-01
  • 2018-02-05
  • 1970-01-01
  • 2022-08-11
  • 1970-01-01
  • 2017-05-02
  • 1970-01-01
  • 2013-04-17
相关资源
最近更新 更多