Google-Gson注解使用详解

简介

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
      反序列化同理.复制代码
  • 二, @SerializedName (做用域field)
    这个注解只是用于映射数据的key用的。好比经常使用的json的key.
    上面的例子。若是在id属性上加个@SerializedName("_id"). 将会输出
    {"_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 !!!

相关文章
相关标签/搜索