2013-02-19 113 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"}