gpt4 book ai didi

java - 使用 GSON 解析没有特定结构的字段的 JSON

转载 作者:行者123 更新时间:2023-11-30 11:53:47 32 4
gpt4 key购买 nike

我正在使用 EmpireAvenue API 开发 Android 应用程序。API 使用 JSON,我使用 GSON 库解析来自 API 的数据。这是问题所在:

我有一个像这样的 JSON 结构:

{
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 结构吗?

感谢您的帮助。

最佳答案

当前使用 Gson 的解决方案有点复杂,需要实现自定义 Instance Creator 和/或自定义 Deserializer。看看http://code.google.com/p/google-gson/issues/detail?id=231the release notes on Hierarchical Type Adapters了解详情。我刚刚发布了一个使用 Gson 进行多态反序列化的示例,以响应 Polymorphism with gson .

Gson 希望很快就会有 RuntimeTypeAdapter 来实现更简单的多态反序列化。参见 http://code.google.com/p/google-gson/issues/detail?id=231了解更多信息。

另一方面,Jackson基于的解决方案还不错。

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();
}
}

关于java - 使用 GSON 解析没有特定结构的字段的 JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6089193/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com