Gson 是一個強大的序列化和反序列化的一個json庫。能夠不徹底按照json格式。java
一, @Expose: 暴露的意思,做用於field, 搭配GsonBuilder使用。使用步驟:json
1, 假設有下面這樣一個數據實體api
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對象。bash
Gson gson = new GsonBuilder() .excludeFieldsWithoutExposeAnnotation().create();複製代碼
3, 序列化數據. ide
StudentModuleImpl module = new StudentModuleImpl();
module.setName("heaven7");
module.setId("xxx");
module.setAge(25);
String json = gson.toJson(module, StudentModuleImpl.class);
log(json);複製代碼
獲得輸出:ui
{"id":"xxx"}複製代碼
只序列化了id屬性。why ?
答案很簡單: this
由於這裏咱們的gson使用了gsonBuilder的excludeFieldsWithoutExposeAnnotation()方法來構造.
它表示任何沒有被@Expose註解的字段都將被忽略, 而且即便用了@Expose但serialize=false 時也不會被序列化。
ps: 默認Expose: serialize = true, deserialize= true
反序列化同理.複製代碼
{"_id":"xxx"}複製代碼
三, @Since 和 @Until
這2個註解用於表示數據序列化的最先版本since(自從),和最晚版本until(直到).
也是搭配GsonBuilder使用的。
使用例子:google
1, 假設有這樣一個數據實體.spa
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();code
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 !!!