使用jackson映射一个未命名的数组

时间:2011-09-25 08:28:11

标签: java json twitter jackson

在没有指定游标的情况下点击twitter friends/ids API端点将返回此JSON响应:

["243439460","13334762", "14654522"]

但是在指定游标时,您将获得记录的格式:

{"next_cursor":0,"previous_cursor":0,"ids":["243439460","13334762","14654522"]}

使用Jackson可以轻松地将第二个响应反序列化

@JsonIgnoreProperties(ignoreUnknown = true)
public class FriendIds {
private List<String> ids;

public List<String> getIds() { return ids; }

public void setIds(List<String> ids) { this.ids = ids; }
}

FriendIds friendIds = new ObjectMapper().readValue(jsonStr, FriendIds.class);

但是我没有找到类似的方法来使用杰克逊对FriendIds的第一个回复进行反序列化。关于如何做到这一点的任何想法?

2 个答案:

答案 0 :(得分:5)

如何将它们首先映射到id列表如下:

List<String> ids = mapper.readValue(json, List.class); // works because String happens to be 'natural' type for JSON Strings

然后只构造包装器对象?

杰克逊没有真正的方法知道JSON数组用于构造POJO,其中一个字段是包含列表的内容,除非编写自定义反序列化器。 如果你想这样做,这是可能的;这实际上可以支持这两种情况。但需要一些思考,为JSON对象使用一个方法(默认POJO deser),为JSON数组使用另一个方法。 所以在杰克逊之外做这件事可能最容易。

答案 1 :(得分:2)

我希望这会有所帮助。您可以使用Spring RestTemplate.getForObject和Jackson注释来完成此任务。

这是Twitter响应的类:

import java.util.List;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

public class TwitterResponse {
  private List<TwitterId> ids;

  @JsonCreator
  public TwitterResponse(List<TwitterId> ids) {
    this.ids = ids;
  }

  public List<TwitterId> getIds() {
    return ids;
  }

  @Override
  public String toString() {
    return "TwitterResponse [ids=" + ids + "]";
  }

}

这是TwitterId类:

import com.fasterxml.jackson.annotation.JsonProperty;

public class TwitterId {

  private String twitterId;

  public TwitterId(String twitterId) {
    this.twitterId = twitterId;
  }

  public String getTwitterId() {
    return twitterId;
  }

  @Override
  public String toString() {
    return "TwitterId [twitterId=" + twitterId + "]";
  }

}

一个简单的单元测试显示它有效。我刚刚创建了一个简单的控制器,可以返回上面的数据,并且我使用RestTemplate进行测试

import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.client.RestTemplate;

public class ControllerTest {
  private static final Logger log = LoggerFactory.getLogger(ControllerTest.class);
@Test
  public void testTwitter() {
    try {
      RestTemplate restTemplate = new RestTemplate();

      TwitterResponse twitterResponse =
          restTemplate.getForObject("http://localhost:8080/twitter",
              TwitterResponse.class);

      log.debug("twitterResponse = {}", twitterResponse);
    } catch (Exception e) {
      e.printStackTrace();
    }

  }

}

控制台显示测试结果:

19:57:42.506 [main] DEBUG org.springframework.web.client.RestTemplate - Created GET request for "http://localhost:8080/twitter"
19:57:42.545 [main] DEBUG org.springframework.web.client.RestTemplate - Setting request Accept header to [application/json, application/*+json]
19:57:42.558 [main] DEBUG org.springframework.web.client.RestTemplate - GET request for "http://localhost:8080/twitter" resulted in 200 (OK)
19:57:42.559 [main] DEBUG org.springframework.web.client.RestTemplate - Reading [class org.porthos.simple.TwitterResponse] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@4b5a5ed1]
19:57:42.572 [main] DEBUG org.porthos.simple.ControllerTest - twitterResponse = TwitterResponse [ids=[TwitterId [twitterId=243439460], TwitterId [twitterId=13334762], TwitterId [twitterId=14654522]]]