• Gson(http://www.jianshu.com/p/e740196225a4)


    • Serialization:序列化,使Java对象到Json字符串的过程。
    • Deserialization:反序列化,字符串转换成Java对象。

    Gson解决的问题

    1. 提供一种像toString()和构造方法的很简单的机制,来实现Java 对象和Json之间的互相转换。

    2. 允许已经存在的无法改变的对象,转换成Json,或者Json转换成已存在的对象。

    3. 允许自定义对象的表现形式

    4. 支持任意的复杂对象

    5. 能够生成可压缩和可读的Json的字符串输出。


    Gson处理对象的几个重要点

    1 推荐把成员变量都声明称private的

    2 没有必要用注解(@Expose 注解)指明某个字段是否会被序列化或者反序列化,所有包含在当前类(包括父类)中的字段都应该默认被序列化或者反序列化

    3 如果某个字段被 transient 这个Java关键词修饰,就不会被序列化或者反序列化

    4 下面的实现方式能够正确的处理null
    1)当序列化的时候,如果对象的某个字段为null,是不会输出到Json字符串中的。
    2)当反序列化的时候,某个字段在Json字符串中找不到对应的值,就会被赋值为null

    5 如果一个字段是 synthetic
    的,他会被忽视,也即是不应该被序列化或者反序列化

    6 内部类(或者anonymous class(匿名类),或者local class(局部类,可以理解为在方法内部声明的类))的某个字段和外部类的某个字段一样的话,就会被忽视,不会被序列化或者反序列化

    Gson的基本用法

    int i = gson.fromJson("100", int.class);
    String jsonNumber = gson.toJson(100);
    
    User user = new User("怪盗kidou",24);
    String jsonObject = gson.toJson(user);
    
    String jsonString = "{"name":"怪盗kidou","age":24}";
    User user = gson.fromJson(jsonString, User.class);

     @SerializedName 注解重命名属性

    使用这个注解注释的属性,在json中,将会使用新的名字来进行对应

    注解有两个参数 value——对于序列化和反序列化都好使    alternate——只有反序列化好使

    @SerializedName(value = "emailAddress", alternate = {"email", "email_address"})
    public String emailAddress;

    比如说,客户端传回来一张图片,不管参数是img、imgine,我都能通过alternate参数来影射成POJO类中的对应的那个参数,非常的方便。

    Gson中使用泛型

    如果要处理数组类型非常的简单:

    Gson gson = new Gson();
    String jsonArray = "['Android','Java','PHP']";
    String[] strings = gson.fromJson(jsonArray, String[].class);

    但是像要处理集合类就比较困难了,因为直接使用List<String>.class 得到的就是List的类,并不能知道里面的泛型的类型
    对于Java来说List<String> 和List<User> 这俩个的字节码文件只一个那就是List.class,这是Java泛型使用时要注意的问题 泛型擦除。

    这里就需要使用TypeToken来进行处理了

    List<String> stringList = gson.fromJson(jsonArray, new TypeToken<List<String>>() {}.getType());

    GsonBuilder

    一般情况下Gson类提供的 API已经能满足大部分的使用场景,但我们需要更多更特殊、更强大的功能时,这时候就引入一个新的类 GsonBuilder,这个类用于配置Gson的默认配置。

    GsonBuilder用法

    Gson gson = new GsonBuilder()
                   //各种配置
                   .create(); //生成配置好的Gson

    实际上是产生了Gson的实例,但是在中间增加了一些配置,只要的配置有:
    1,Gson在默认情况下,是不会序列化值为null的键的。

    Gson gson = new GsonBuilder().serializeNulls().create();  //这样就会序列化值为null的键了

    2,其他的配置

    Gson gson = new GsonBuilder()
            //序列化null
            .serializeNulls()
            // 设置日期时间格式,另有2个重载方法
            // 在序列化和反序化时均生效
            .setDateFormat("yyyy-MM-dd")
            // 禁此序列化内部类
            .disableInnerClassSerialization()
            //生成不可执行的Json(多了 )]}' 这4个字符)
            .generateNonExecutableJson()
            //禁止转义html标签
            .disableHtmlEscaping()
            //格式化输出
            .setPrettyPrinting()
            .create();

    字段过滤的几种方法

    1,@Expose注解

    注解作用在属性上,有两个参数值 deserialize和serialize,默认为true,如果设置为false,那么对应的字段就不会被序列化/反序列化

    这里实例化Gson的时候需要使用GsonBuilder

    Gson gson = new GsonBuilder()
            .excludeFieldsWithoutExposeAnnotation()
            .create();
    gson.toJson(category);

    2,@Since 和 @Until注解

    基于版本号,只有在某些版本上,字段才有效,使用GsonBuilder来进行版本的监控

    new GsonBuilder().setVersion(1.2).create();

    3,基于访问修饰符

    这个跟基于@Expose的很类似,只是排除了特定修饰符的方法。

    Gson gson = new GsonBuilder()
            .excludeFieldsWithModifiers(Modifier.FINAL, Modifier.STATIC, Modifier.PRIVATE)
            .create();

    4,基于策略,使用自定义的规则

      //通过一个内部类,完成了自定义的字段的筛选,这里是指定了反序列化的规则,还可以使用序列化函数指定序列化的规则
    Gson g2=new GsonBuilder().addDeserializationExclusionStrategy(
               new ExclusionStrategy() {
                @Override
                public boolean shouldSkipField(FieldAttributes f) {
                    //返回true的就是要排除的,这里是根据字段来排除
                    if ("name".equals(f.getName())) return true; //按字段名排除
                    Expose expose = f.getAnnotation(Expose.class);
                    if (expose != null && expose.deserialize() == false) return true; //按注解排除
                    return false;
                }
                @Override
                public boolean shouldSkipClass(Class<?> clazz) {
                    //返回true的就是要排除的,这里是根据字段的类来排除
                    if(clazz.equals(int.class)) //直接排除了int型的属性
                        return true;
                    return false;
                }
            }).create();

     一些简单的例子:

    Gson ggg=new GsonBuilder().setDateFormat("yyyy-mm-dd").serializeNulls().create();

    设置了时间的格式,并且要求对于null的属性也进行序列化

  • 相关阅读:
    关于this的指向问题
    blued面经
    数美(sm)面经
    xue球 面经
    jquery中的$("#id")与document.getElementById("id")的区别
    如何知道iframe文件下载download完成
    前端linux基础
    Vue.js 初级面试题
    React 面试题
    从输入URL到页面加载的过程
  • 原文地址:https://www.cnblogs.com/Coder-Pig/p/7396930.html
Copyright © 2020-2023  润新知