2010-03-03 134 views
72

我正在使用GSON将JSON数据转换为Java对象。它在我所有的测试中都能很好地工作。 问题是我们的真实对象有一些像is_online这样的属性。 GSON只会映射它们,如果它们命名完全相同,那么让GSON将名称转换为Java驼峰案例isOnline会很好。使用GSON将JSON样式属性名称转换为Java CamelCase名称

看起来,这是可能的,同时创建JSON数据,骆驼大小写转换为JSON中的下划线分隔的单词。但我无法找到一种方法来反过来指定这一点。

+3

我会建议接受一个答案 – JeanValjean 2016-03-01 23:05:40

回答

2

请记住,你的例子是一个边缘案例。如果你有一个属性'foo',它的getter应该被命名为'getFoo',并且如果你有一个名为'foo_bar'的属性,它的getter应该被命名为'getFooBar',但是在你的例子中,你正在映射布尔和布尔值java中的特殊情况命名约定。名为online的原始布尔属性应该有一个名为'isOnline',不'getOnline'或更糟糕的'getIsOnline'的getter。一个布尔封装器对象(即布尔)不应该遵循这种特殊情况,名为'online'的属性应该有一个名为'getOnline'的getter。

因此,在名称中带有'is'的布尔属性是一种边缘情况,您需要在转换过程中去掉此特定前缀。在相反的方向上,你的代码可能想要检查json对象的原始属性名称以及'is_XXX'版本。

2

我想你想要的是here。使用注释可以告诉GSON,mySuperCoolField实际上在JSON中被称为this_field_is_fun,并且它会正确地解压缩它。至少我认为它也适用于反序列化。

如果这不起作用,您可以使用自定义的JsonSerializer/JsonDeserializers,这很好用,但您必须更新它们以获取类中的更改(例如添加字段时)。你失去了自动魔法。

最容易做的事情(如果第一个建议不起作用,这将是丑陋的,但非常干净和简单)只需简单命名该字段以使GSON快乐,并添加额外的存取器方法你喜欢的名字,例如

public boolean isXXX() {return this.is_XXX;} 
+0

简单的事情就是我现在正在做的事情,它工作得很好。所有丑陋的不典型的java风格的代码都隐藏在数据类中,没有人会从外面看到它。但它仍然唠叨我一点:) – Janusz 2010-09-09 14:45:30

206

我发现以下设置在阅读带有下划线属性的json和在我的模型中使用camelcasing时非常完美。

Gson gson = new GsonBuilder() 
    .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) 
    .create() 
+15

这应该是一个公认的答案。 – 2014-11-13 14:00:50

+2

很好的答案,谢谢! @janusz,如果这些答案中的任何一条对你有帮助,请将它们标记为“已接受的答案”。 – sufinawaz 2014-12-22 22:08:48

+1

如果您有一个名称包含两个下划线的情况,它会忽略第一个下划线。防爆。 this_key_has__two_underscores将被转换为thisKeyHas_TwoUnderscores,反之亦然。关键点是FieldNamingPolicy,其中枚举用小写字母表示“小写字母”,而此处转换后的名称带有下划线(_T)的大写字母。 – 2016-05-13 07:44:20

62

可以使用SerializedName注释:

@SerializedName("field_name_in_json") 
private final String fieldNameInJava; 

注意:当您设置了FieldNamingPolicy已经,SerializedName将覆盖其设置为特定领域(很方便在特殊情况下)。