简介
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 !!!