解析JSON无特定结构用于与GSON一个字段 [英] Parse JSON with no specific structure for a field with GSON

查看:563
本文介绍了解析JSON无特定结构用于与GSON一个字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我工作的Andr​​oid应用程序,使用EmpireAvenue API。 该API使用JSON和我使用GSON库来解析从API的数据。 这里的问题是:

I am working on an Android application, using the EmpireAvenue API. The API uses JSON and I'm using the GSON library to parse the data from the API. Here is the problem:

我有这样一个JSON结构:

I have a JSON structure like this:

{
    type: "earnings",
    info: {
        earnings: 64.09
        dividends: 1277.34
        gains: 1997.05
        expenses: 4895.51
        shares_bought: 210
        shares_bought_user_count: 2
        shares_sold: 0
        shares_sold_user_count: 0
    },
    created: "2011-04-16 11:32:37"
},
{
    type: "following",
    info: [
            {
                ticker: "SOLPHE"
                full_name: "Rodrigo Bermudez Salazar"
                list_name: "My Recommended Buys"
            },
            {
                ticker: "SOLPHE"
                full_name: "Rodrigo Bermudez Salazar"
                list_name: "My Watch List"
            }
          ],
    created: "2011-04-16 11:00:08"
}

正如你所看到的,与信息领域相关的结构不同。有时,它是一个对象,有时是一个数组。正如所料,GSON库在解析时抛出错误。 你知道如何解析的JSON结构,当一个领域的结构变化?

As you can see, the structure associated with the info field is different. Sometimes it's an object, sometimes an array. As expected, the GSON library throws errors when parsing. Do you know how to parse a JSON structure with when a field changes structure ?

感谢您的帮助。

推荐答案

目前的解决方案与GSON是有点麻烦,需要实现定制的实例创建和/或自定义解串器。看看的http:// code .google.com / P /谷歌GSON /问题/详细信息?ID = 231 和的发行分层型适配器说明了解详细信息。我刚刚发布的多态反序列化的一个实例与GSON响应多态性与GSON

The current solution with Gson is a bit involved, requiring implementation of a custom Instance Creator and/or a custom Deserializer. Take a look at http://code.google.com/p/google-gson/issues/detail?id=231 and the release notes on Hierarchical Type Adapters for details. I just posted an example of polymorphic deserialization with Gson in response to Polymorphism with gson.

GSON希望很快就会有 RuntimeTypeAdapter 更简单的多态反序列化。请参见 HTTP://$c$c.google。 COM / P /谷歌GSON /问题/详细信息?ID = 231 获取更多的信息。

Gson hopefully will soon have the RuntimeTypeAdapter for simpler polymorphic deserialization. See http://code.google.com/p/google-gson/issues/detail?id=231 for more info.

在另一方面,一个杰克逊为基础的解决方案并没有那么糟糕。

On the other hand, a Jackson-based solution isn't so bad.

public class Foo
{
  static String jsonInput =
  "[" + 
    "{" + 
      "\"type\":\"earnings\"," + 
      "\"info\":" + 
      "{" + 
        "\"earnings\":64.09," + 
        "\"dividends\":1277.34," + 
        "\"gains\":1997.05," + 
        "\"expenses\":4895.51," + 
        "\"shares_bought\":210," + 
        "\"shares_bought_user_count\":2," + 
        "\"shares_sold\":0," + 
        "\"shares_sold_user_count\":0" + 
      "}," + 
      "\"created\":\"2011-04-16 11:32:37\"" + 
    "}," + 
    "{" + 
      "\"type\":\"following\"," + 
      "\"info\":" + 
      "[" + 
        "{" + 
          "\"ticker\":\"SOLPHE\"," + 
          "\"full_name\":\"RodrigoBermudezSalazar\"," + 
          "\"list_name\":\"MyRecommendedBuys\"" + 
        "}," + 
        "{" + 
          "\"ticker\":\"SOLPHE\"," + 
          "\"full_name\":\"RodrigoBermudezSalazar\"," + 
          "\"list_name\":\"MyWatchList\"" + 
        "}" + 
      "]," + 
      "\"created\":\"2011-04-16 11:00:08\"" + 
    "}" + 
  "]";

  public static void main(String[] args) throws Exception
  {
    ObjectMapper mapper = new ObjectMapper();
    mapper.setPropertyNamingStrategy(new CamelCaseNamingStrategy());
    DateFormat dataFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    mapper.setDateFormat(dataFormat);
    Collection<Thing> things = mapper.readValue(jsonInput, new TypeReference<Collection<Thing>>(){});
    System.out.println(things);
  }
}

@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.PROPERTY, property="type")
@JsonSubTypes({@Type(value=Earnings.class, name="earnings"), @Type(value=Following.class, name="following")})
abstract class Thing
{
  private Date created;

  void setCreated(Date created)
  {
    this.created = created;
  }

  @Override
  public String toString()
  {
    return String.format(
        "[%1$s: created=%2$s, other attributes:%3$s]",
        getClass().getSimpleName(), created, toStringAddenda());
  }

  abstract String toStringAddenda();
}

class Earnings extends Thing
{
  private EarningsInfo info;

  void setInfo(EarningsInfo info)
  {
    this.info = info;
  }

  @Override
  String toStringAddenda()
  {
    return info.toString();
  }
}

class Following extends Thing
{
  private Collection<FollowingInfo> info;

  void setInfo(Collection<FollowingInfo> info)
  {
    this.info = info;
  }

  @Override
  String toStringAddenda()
  {
    return info.toString();
  }
}

class FollowingInfo
{
  private String ticker;
  private String fullName;
  private String listName;

  void setTicker(String ticker)
  {
    this.ticker = ticker;
  }

  void setFullName(String fullName)
  {
    this.fullName = fullName;
  }

  void setListName(String listName)
  {
    this.listName = listName;
  }

  @Override
  public String toString()
  {
    return String.format(
        "[FollowingInfo: ticker=%1$s, fullName=%2$s, listName=%3$s]",
        ticker, fullName, listName);
  }
}

class EarningsInfo
{
  private BigDecimal earnings;
  private BigDecimal dividends;
  private BigDecimal gains;
  private BigDecimal expenses;
  private int sharesBought;
  private int sharesBoughtUserCount;
  private int sharesSold;
  private int sharesSoldUserCount;

  void setEarnings(BigDecimal earnings)
  {
    this.earnings = earnings;
  }

  void setDividends(BigDecimal dividends)
  {
    this.dividends = dividends;
  }

  void setGains(BigDecimal gains)
  {
    this.gains = gains;
  }

  void setExpenses(BigDecimal expenses)
  {
    this.expenses = expenses;
  }

  void setSharesBought(int sharesBought)
  {
    this.sharesBought = sharesBought;
  }

  void setSharesBoughtUserCount(int sharesBoughtUserCount)
  {
    this.sharesBoughtUserCount = sharesBoughtUserCount;
  }

  void setSharesSold(int sharesSold)
  {
    this.sharesSold = sharesSold;
  }

  void setSharesSoldUserCount(int sharesSoldUserCount)
  {
    this.sharesSoldUserCount = sharesSoldUserCount;
  }

  @Override
  public String toString()
  {
    return String.format(
        "[EarningsInfo: earnings=%1$s, dividends=%2$s, gains=%3$s, expenses=%4$s, sharesBought=%5$s, sharesBoughtUserCount=%6$s, sharesSold=%7$s, sharesSoldUserCount=%8$s]",
        earnings, dividends, gains, expenses, sharesBought, sharesBoughtUserCount, sharesSold, sharesSoldUserCount);
  }
}

class CamelCaseNamingStrategy extends PropertyNamingStrategy
{
  @Override
  public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName)
  {
    return convert(defaultName);
  }

  @Override
  public String nameForSetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName)
  {
    return convert(defaultName);
  }

  @Override
  public String nameForField(MapperConfig<?> config, AnnotatedField field, String defaultName)
  {
    return convert(defaultName);
  }

  private String convert(String defaultName)
  {
    char[] nameChars = defaultName.toCharArray();
    StringBuilder nameTranslated = new StringBuilder(nameChars.length * 2);
    for (char c : nameChars)
    {
      if (Character.isUpperCase(c))
      {
        nameTranslated.append("_");
        c = Character.toLowerCase(c);
      }
      nameTranslated.append(c);
    }
    return nameTranslated.toString();
  }
}

这篇关于解析JSON无特定结构用于与GSON一个字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆