【问题标题】:Using jackson to map an unnamed array使用杰克逊映射一个未命名的数组
【发布时间】:2011-11-24 13:24:48
【问题描述】:

在没有指定游标的情况下点击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);

但是我还没有找到类似的方法来反序列化使用 Jackson 对FriendIds 的第一个响应。关于如何做到这一点的任何想法?

【问题讨论】:

  • 第一个响应不是 JSON - 它只是一个数组
  • @IgorDymov 是的。我最初是这么想的,但是我把它扔给了验证者接受了它。 jsonlint.com
  • 是合法的JSON,没问题,但是作为数组需要映射到数组或者集合......

标签: java json twitter jackson


【解决方案1】:

先将它们映射到 id 列表怎么样:

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

然后只是构造包装对象?

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

【讨论】:

    【解决方案2】:

    我希望这会有所帮助。您可以使用 Spring RestTemplate.getForObject 和 Jackson 注释来做到这一点。

    这是 Twitter Response 的类:

    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]]]
    

    【讨论】:

      猜你喜欢
      • 2012-10-01
      • 1970-01-01
      • 2013-04-11
      • 1970-01-01
      • 2014-11-22
      • 1970-01-01
      • 2011-10-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多