1. 基本使用方法[fromJson/toJson]
      将字符串解析成相应的对象 or 将对象Json化 这个应该是最常用的吧 ```java Gson gson = new Gson(); String result = gson.fromJson(“str”,String.class); int result1 = gson.fromJson(“100”,int.class); Double result2 = gson.fromJson(“210.34”,Double.class);

    Person person = new Person(); result = gson.toJson(person)

    1. 2.属性名不一致情况 使用@SerializedName<br />这个问题主要是三端(server/前端/客户端)命名习惯不一致造成的,举个例子:
    2. ```java
    3. // 客户端 java:
    4. private String userName = "zhangsan";
    5. //前端 javascript:
    6. let user_name = "zhangsan"
    7. //后端 PHP:
    8. $username = "zhangsan";

    那么相应的json为:
    “{‘userName’:’zhangsan’}”
    “{‘user_name’:’zhangsan’}”
    “{‘username’:’zhangsan’}”

    最为客户端,需要兼容这些模式时,需要使用@SerializedName:

    1. @SerializedName(value = "userName", alternate = {"user_name","username"})
    2. public String userName;

    其中value是当前默认解析字段,没有的话,查找有没有user_name或者username,有的话,将对应的值映射到该字段上。相当于alernate关键字是备选字段。

    1. 使用GsonBuilder输出null
      我们定义一个对象Student:

      1. public class Student {
      2. private String name ;
      3. private int age ;
      4. //getter.setter方法
      5. }

    默认情况下,null字段是不输出的:

    1. Student s = new Student();
    2. String str = gson.toJson(s);
    3. System.out.println(str)

    结果为:
    {“age”:0}

    如果需要输入name,那么需要定义GsonBuilder:

    1. //自定义GsonBuilder
    2. Gson gson = new GsonBuilder().serializeNulls().create();
    3. gson.toJson(s, System.out);

    输出为:
    {“name”:null,”age”:0}

    4.输出格式化Gson
    Gson gson2 = new GsonBuilder().serializeNulls().setPrettyPrinting().create();

    输出:

    1. {
    2. "name": null,
    3. "age": 0
    4. }

    5.设置时间格式:
    Gson gson2 = new GsonBuilder().setDateFormat(“yyyy-MM-dd”).create();
    gson2.toJson(new java.util.Date(), System.out);

    输出为:
    “2018-07-09”

    6.生成不可以用的Json字符串[貌似没什么卵用]
    Gson gson2 = new GsonBuilder().setDateFormat(“yyyy-MM-dd”).generateNonExecutableJson().create();
    gson2.toJson(new java.util.Date(), System.out);

    输出为:
    )]}’
    “2018-07-09”

    7.禁止Html字符串转义:
    String html = “

    hello world

    “ ;

    Gson gson2 = new GsonBuilder().disableHtmlEscaping().create();
    gson2.toJson(html,System.out);

    禁止字符转义之后,变为:

    hello world


    未禁止转义之后:
    “\u003cp\u003e hello world\u003c/p\u003e” //UTF-8转义

    8.字段过滤
    主要的原因是安全因素,人为添加字段,有时候序列化&反序列化需要过滤这些字段:

    8.1 @Expose字段:
    Expose中文名称是曝光的意思,就是你添加了,它就会序列化/反序列化了,没有的话就算了。

    Student类中添加”address”字段:

    1. public class Student {
    2. private String name ;
    3. private int age ;
    4. @Expose(serialize = true, deserialize = true)
    5. private String address;
    6. }

    那么toGson为:

    1. Student student = new Student("tom",12,"sh");
    2. Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
    3. gson.toJson(student,System.out);

    输出为:
    {“address”:”sh”}

    当然@Expost注解上还有serialize和deserialize关键字,按字面意思在序列化和反序列化时,要不要将该字段接入操作。

    另外还有简单的做法,你再服务器中查询到敏感属性不希望被实例化,可以在属性加上transient修饰符修饰:

    1. public class User {
    2. public long id;
    3. public String userName;
    4. //我不希望被实例化到Json中,可以加上transient 即可
    5. public transient String userPassword;
    6. public transient String userHash;
    7. public String userImage;
    8. }

    8.2 基于版本,基于注解@Until和@Since
    @Until是 <= 某Version
    @Since是 >= 某Version

    @Since(18)
    private int age ;

    设置当前版本:
    Student student = new Student(“tom”,12,”sh”);
    Gson gson = new GsonBuilder().setVersion(17).create();
    gson.toJson(student,System.out);

    当前设置版本17 < @Since(18)此时,此时将不会输出age:
    {“name”:”tom”,”address”:”sh”}

    更改Version:
    Gson gson = new GsonBuilder().setVersion(20).create();
    当前设置版本20 > @Since(18)此时,此时输出为:
    {“name”:”tom”,”age”:12,”address”:”sh”}
    同理,@Until也是类似的,将不再做类比了。
    当然对于同一个字段,你可以同时使用@Since和@Until
    @Since(20)
    @Until(5)
    private String address;

    8.3 基于访问修饰符
    设置相应的修饰符对象字段:

    1. public class ModifierTest {
    2. private String privateName = "privateName";
    3. public String publicName = "publicName";
    4. public final String finalName = "finalName";
    5. public final static String finalStaticName = "finalStaticName";
    6. }

    使用Modifier字段过滤:
    ModifierTest test = new ModifierTest();
    //去除private修饰符字段
    Gson gson = new GsonBuilder().excludeFieldsWithModifiers(Modifier.PRIVATE).create();
    gson.toJson(test,System.out);
    输出为:
    {“publicName”:”publicName”,”finalName”:”finalName”,”finalStaticName”:”finalStaticName”}
    去掉final 和 public字段:
    Gson gson = new GsonBuilder().excludeFieldsWithModifiers(Modifier.FINAL, Modifier.PUBLIC).create();
    输出为:
    {“privateName”:”privateName”}

    8.4 自定义规则
    直接使用Gson中提供的ExclusionStrategy接口:

    1. Student student = new Student("tom",12,"sh");
    2. Gson gson = new GsonBuilder().addSerializationExclusionStrategy(new ExclusionStrategy() {
    3. //跳过的field将不参与序列化/反序列化
    4. @Override
    5. public boolean shouldSkipField(FieldAttributes f) {
    6. //name 直接跳过
    7. if("name".equals(f.getName())) return true;
    8. Expose expose = f.getAnnotation(Expose.class);
    9. if(expose != null && !expose.deserialize()) return true ; //按照Expose注解 跳过
    10. return false;
    11. }
    12. @Override
    13. public boolean shouldSkipClass(Class<?> clazz) {
    14. //直接排除某些特定的类
    15. return clazz == int.class || clazz == Integer.class;
    16. }
    17. }).create();
    18. gson.toJson(student, System.out);

    输出为:
    {“address”:”sh”}

    1. 自定义TypeAdapter
      很多时候,我们都会遇到这种情况,我们定义age字段是int型的,但是服务器给我们返回的是””字段,如果不做处理,使用Gson解析就会抛出NumberFormatException,所以为了解决这个容错性,你不可能把后端拉出来打一顿,所以只有另想它法。
      幸好Gson提供了TypeAdapter抽象类,可以抽象解析我们需要的数据,来个简单一点的,直接解析注册Int.class解析器: ```java String personUrl = “{\”name\” : \’zhangsan\’ , \’age\’ : ‘’ , \’address\’ : \’sh\’}” ;

    Gson gson = new GsonBuilder().registerTypeAdapter(int.class, new TypeAdapter() {

    @Override public void write(JsonWriter out, Integer value) throws IOException { out.value(String.valueOf(value)); }

    @Override public Integer read(JsonReader in) throws IOException { String value = in.nextString(); //System.out.println(“———>>” + value);

    1. try {
    2. return Integer.parseInt(value);
    3. }catch (NumberFormatException ignore){
    4. return -1;
    5. }
    6. }
    7. }).create() ;
    8. Person person = gson.fromJson(personUrl, Person.class);
    9. System.out.println(person);
    1. 解析之后,此时的空字符串被解析成了-1:<br />Person{name='zhangsan', age=-1, address='sh'}<br />如果需要解析Student呢:<br />同样一个道理:
    2. ```java
    3. public class StudentTypeAdapter extends TypeAdapter<Student> {
    4. @Override
    5. public void write(JsonWriter out, User value) throws IOException {
    6. out.beginObject();
    7. out.name("name").value(out.name);
    8. out.name("age").value(out.age);
    9. out.name("address").value(out.address);
    10. out.endObject();
    11. }
    12. @Override
    13. public Student read(JsonReader in) throws IOException {
    14. Student student = new Student();
    15. in.beginObject();
    16. while(in.hasNext()) {
    17. switch(in.nextName()) {
    18. case "name":
    19. student.name = in.nextString();
    20. break;
    21. case "age" :
    22. student.age = int.nextInt();
    23. break;
    24. case "address":
    25. student.address = int.nextString();
    26. break ;
    27. }
    28. }
    29. in.endObject();
    30. }
    31. }
    1. Gson与混淆
      当代码需要混淆时,有gson参与时,需要注意以下几点:

    需要序列化的类,不能被混淆;
    使用泛型参与解析的基类BaseEntity需要实现java.io.Serializable接口。

    11.解析 List 类型的Json串

    1. Gson gson = new Gson();
    2. Type type = new TypeToken<List<Object>>() {}.getType();
    3. List<Object> list = gson.fromJson(string, type);

    ————————————————
    版权声明:本文为CSDN博主「microhex」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/u013762572/article/details/80973912