簡介
Gson 是一個強大的序列化和反序列化的一個json庫。可以不完全按照json格式。
各註解說明
一, @Expose: 暴露的意思,作用於field, 搭配GsonBuilder使用。使用步驟:
1, 假設有下面這樣一個資料實體
public class StudentModuleImpl{ private int age; @Expose( serialize = false, deserialize = false ) private String name; @Expose() private String id; @Override public int getAge() { return age; } @Override public void setAge(int age) { this.age = age; } @Override public String getName() { return name; } @Override public void setName(String name) { this.name = name; } @Override public String getId() { return id; } @Override public void setId(String id) { this.id = id; } @Override public String toString() { return "StudentModuleImpl{" + "name='" + name + '\'' + ", age=" + age + ", id='" + id + '\'' + '}'; } }複製程式碼
2, 使用 excludeFieldsWithoutExposeAnnotation方法構造gson物件。
Gson gson = new GsonBuilder() .excludeFieldsWithoutExposeAnnotation().create();複製程式碼
3, 序列化資料.
StudentModuleImpl module = new StudentModuleImpl(); module.setName("heaven7"); module.setId("xxx"); module.setAge(25); String json = gson.toJson(module, StudentModuleImpl.class); log(json);複製程式碼
得到輸出:
{"id":"xxx"}複製程式碼
只序列化了id屬性。why ?
答案很簡單:因為這裡我們的gson使用了gsonBuilder的excludeFieldsWithoutExposeAnnotation()方法來構造. 它表示任何沒有被@Expose註解的欄位都將被忽略, 並且即使用了@Expose但serialize=false 時也不會被序列化。 ps: 預設Expose: serialize = true, deserialize= true 反序列化同理.複製程式碼
- 二, @SerializedName (作用域field)
這個註解只是用於對映資料的key用的。比如常用的json的key.
上面的例子。如果在id屬性上加個@SerializedName("_id"). 將會輸出{"_id":"xxx"}複製程式碼
三, @Since 和 @Until
這2個註解用於表示資料序列化的最早版本since(自從),和最晚版本until(直到).
也是搭配GsonBuilder使用的。
使用例子:1, 假設有這樣一個資料實體.
public class Car3 { @Since(2.0) private String mark; @Since(2.1) private int model; @Until(1.9) private String type; @Until(2.1) private String maker; private double cost; private List<String> colors = new ArrayList<String>(); public String getMark() { return mark; } public void setMark(String mark) { this.mark = mark; } public int getModel() { return model; } public void setModel(int model) { this.model = model; } public String getType() { return type; } public void setType(String type) { this.type = type; } public String getMaker() { return maker; } public void setMaker(String maker) { this.maker = maker; } public double getCost() { return cost; } public void setCost(double cost) { this.cost = cost; } public List<String> getColors() { return colors; } public void setColors(List<String> colors) { this.colors = colors; } @Override public String toString() { return "Car3 [mark=" + mark + ", model=" + model + ", type=" + type \+ " , maker=" + maker + ", cost=" + cost + ", colors=" + colors + "]"; } }複製程式碼
2, 設定屬性並序列化
//這裡設定當前版本為2.0. 那麼since大於2.0的不被序列化和反序列化。
//until小於2.0的不被序列化和反序列化。
Gson gson = new GsonBuilder().setVersion(2.0).create();Car3 car = new Car3(); car.setMark("AUDI"); car.setModel(2014); //2,1 car.setType("DIESEL"); car.setMaker("AUDI GERMANY"); car.setCost(55000); car.getColors().add("GREY"); car.getColors().add("BLACK"); car.getColors().add("WHITE"); /* Serialize */ String jsonString = gson.toJson(car); System.out.println("Serialized jsonString : " + jsonString);複製程式碼
得到輸出:
Serialized jsonString : {"mark":"AUDI","maker":"AUDI GERMANY","cost":5555.0,"colors":["GREY","BLACK","WHITE"]}複製程式碼
然後我們發現module, type屬性並沒有序列化。原因就是
@Since(2.1) //since 大於設定的2.0
private int model;
@Until(1.9) //until 小雨設定的2.0
private String type;複製程式碼
四, @JsonAdapter.
這個註解的作用可以自定義序列化和反序列化。比如你想給你的HashMap資料自定義序列化和反序列化。
作用範圍: class 和 field. 就是說可以放在類和欄位上.
比如上面的Car3. 我可以用自定義的TypeAdapter.。public class Car3TypeAdapter extends TypeAdapter<Car3> { @Override public void write(JsonWriter writer, Car3 car) throws IOException { writer.beginObject(); writer.name("mark").value(car.getMark()); writer.name("model").value(car.getModel()); writer.name("type").value(car.getType()); writer.name("maker").value(car.getMaker()); double costIncludingVAT = car.getCost() + 0.21 * car.getCost();// Add 21% VAT writer.name("cost").value(costIncludingVAT); writer.name("colors"); writer.beginArray(); for (String color : car.getColors()) { writer.value(color); } writer.endArray(); writer.endObject(); } @Override public Car3 read(JsonReader reader) throws IOException { Car3 car = new Car3(); reader.beginObject(); while (reader.hasNext()) { String name = reader.nextName(); if (name.equals("mark")) { car.setMark(reader.nextString()); } else if (name.equals("model")) { car.setModel(reader.nextInt()); } else if (name.equals("type")) { car.setType(reader.nextString()); } else if (name.equals("maker")) { car.setType(reader.nextString()); } else if (name.equals("cost")) { double cost = reader.nextDouble(); double costExcludingVAT = cost / 1.21; car.setCost(costExcludingVAT); //Remove VAT 21% } else if (name.equals("colors") && reader.peek() != JsonToken.NULL) { car.setColors(readStringArray(reader)); } else { reader.skipValue(); } } reader.endObject(); return car; } public List<String> readStringArray(JsonReader reader) throws IOException { List<String> colors = new ArrayList<String>(); reader.beginArray(); while (reader.hasNext()) { colors.add(reader.nextString()); } reader.endArray(); return colors; } }複製程式碼
然後加上註解
@JsonAdapter(Car3TypeAdapter.class) public class Car3 { ...... }複製程式碼
這樣。以後序列化和反序列化就會用靜態註冊的Car3TypeAdapter. 需要注意的是,
可以動態註冊TypeAdapter. 而且動態註冊優先順序高於靜態註冊的。public GsonBuilder registerTypeAdapter(Type type, Object typeAdapter)複製程式碼
至此,註解是基本說完了。
實際上,gson還有更加豐富的api.比如
//from GsonBuilder public GsonBuilder setExclusionStrategies(ExclusionStrategy... strategies); public GsonBuilder addSerializationExclusionStrategy(ExclusionStrategy strategy) public GsonBuilder addDeserializationExclusionStrategy(ExclusionStrategy strategy) //通過上面3個方法 可以自定義序列化和反序列化的不包含策略。複製程式碼
當然還有。
//註冊 建立TypeAdapter的工廠 public GsonBuilder registerTypeAdapterFactory(TypeAdapterFactory factory) //註冊 建立TypeAdapter(層級關係)的工廠 public GsonBuilder registerTypeHierarchyAdapter(Class<?> baseType, Object typeAdapter)複製程式碼
這個我就不細說了。 google一下很多教程。
thanks for reading !!!