2013-02-19 112 views
5

我的类:如何防止Gson序列化/反序列化字段的第一个字符(下划线)?

class ExampleBean { 
    private String _firstField; 
    private String _secondField; 
    // respective getters and setters 
} 

我希望出现如下:

{ 
    "FirstField":"value", 
    "SecondField":"value" 
} 

而且不喜欢这个

{ 
    "_FirstField":"value", 
    "_SecondField":"value" 
} 

我初始化解析器如下:

GsonBuilder builder = new GsonBuilder(); 
    builder.setDateFormat(DateFormat.LONG); 
    builder.setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE); 
    builder.setPrettyPrinting(); 
    set_defaultParser(builder.create()); 

我可以看到API和“FieldNamePolicy”的documentation但我很惊讶,没有给跳过选项“_” 我也知道我可以使用注释...

@ SerializedName (" custom_naming ") 

...但不希望必须写这全部我的领域...

这是非常有用的区分本地变量和类的字段。 :(任何想法

编辑:?会有很多明显的解决方案,(继承,GSON覆盖方法,定期expresions)我的问题是更侧重于是否有GSON的本地解决方案或干扰较小修复?

也许我们可以提出新的FieldNamePolicy?

+0

答案是...遵循正确的Java命名约定和不使用下划线。即使JSON命名约定允许,你很少会在JSON中找到任何使用PascalCase的人(这就是你提出的输出结果)。您的其他选项是对每个不匹配的字段名称使用“@ SerializedName”。 – 2013-02-19 21:40:34

+0

你没有告诉我任何我不知道的事情。我和我的专业团队,我们可以自由选择我们更加认同的语言惯例。特别是当我们同时整合各种技术和语言时。无论如何,谢谢你的时间。 – enagra 2013-02-20 17:20:14

+0

那么你和你的“专业团队”应该准备好处理由此产生的问题,呃?奇怪的是,我实际上正在输入一个答案,告诉你如何在你评论时用一个自定义的Gson JsonSerializer使用反射来实现它。但我相信你会弄清楚,因为你有一个专业团队...... – 2013-02-20 17:22:44

回答

11

GsonBuilder提供了一种方法setFieldNamingStrategy(),使您可以通过自己的FieldNamingStrategy实现。

注意,这取代了CAL l至setFieldNamingPolicy() - 如果您查看GsonBuilder的来源,这两种方法是相互排斥的,因为它们设置相同的内部字段(FieldNamingPolicy enum FieldNamingStrategy)。

public class App 
{ 
    public static void main(String[] args) 
    { 
     Gson gson = new GsonBuilder() 
         .setFieldNamingStrategy(new MyFieldNamingStrategy()) 
         .setPrettyPrinting() 
         .create(); 

     System.out.println(gson.toJson(new ExampleBean())); 
    } 
} 

class ExampleBean 
{ 

    private String _firstField = "first field value"; 
    private String _secondField = "second field value"; 
    // respective getters and setters 
} 

class MyFieldNamingStrategy implements FieldNamingStrategy 
{ 
    public String translateName(Field field) 
    { 
     String fieldName = 
      FieldNamingPolicy.UPPER_CAMEL_CASE.translateName(field); 
     if (fieldName.startsWith("_")) 
     { 
      fieldName = fieldName.substring(1); 
     } 
     return fieldName; 
    } 
} 

输出:

{ 
    "FirstField": "first field value", 
    "SecondField": "second field value" 
} 
+0

谢谢布莱恩!这真的是最好的解决方案! – enagra 2013-02-20 20:00:27

+0

我试图编辑它,以便编译和工作,但编辑被拒绝。 FieldNamingPolicy上没有translateName()方法。 http://stackoverflow.com/review/suggested-edits/5997458 – Kirby 2014-10-14 21:52:03

+0

@Kirby从1.3版开始https://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/ gson/FieldNamingStrategy.html – Justin 2015-09-01 12:49:48

0

你想要的是

import java.lang.reflect.Field; 
import java.text.DateFormat; 

import com.google.gson.FieldNamingStrategy; 
import com.google.gson.Gson; 
import com.google.gson.GsonBuilder; 

public class GsonExample { 

    public static void main(String... args) throws Exception { 
     final GsonBuilder builder = new GsonBuilder(); 
     builder.setDateFormat(DateFormat.LONG); 
     builder.setPrettyPrinting(); 
     builder.setFieldNamingStrategy(new FieldNamingStrategy() { 
      @Override 
      public String translateName(Field f) { 
       String fieldName = f.getName(); 
       if(fieldName.startsWith("_") && fieldName.length() > 1) { 
        fieldName = fieldName.substring(1, 2).toUpperCase() + fieldName.substring(2); 
       } 
       return fieldName; 
      } 
     }); 
     final Gson gson = builder.create(); 
     System.out.println(gson.toJson(new ExampleBean("example", "bean"))); 
    } 


    private static class ExampleBean { 
     private final String _firstField; 
     private final String _secondField; 

     private ExampleBean(String _firstField, String _secondField) { 
      this._firstField = _firstField; 
      this._secondField = _secondField; 
     } 
    } 
} 

产生

{"FirstField":"example","SecondField":"bean"}