zoukankan      html  css  js  c++  java
  • Gson的学习与使用

    Gson介绍:

    GSON是Google提供的用来在Java对象和JSON数据之间进行映射的Java类库。可以将一个Json字符转成一个Java对象,或者将一个Java转化为Json字符串。
    特点: a、快速、高效
          b、代码量少、简洁
          c、面向对象
            d、数据传递和解析方便
     
    Gson的pom依赖:
            <dependency>
                <groupId>com.google.code.gson</groupId>
                <artifactId>gson</artifactId>
                <version>2.8.0</version>
            </dependency>

    Gson的创建方式:

      方式一:

    Gson gson = new gson();

      方式二:通过GsonBuilder(),可以配置多种配置。

    Gson gson = new GsonBuilder()
                            .setLenient()// json宽松  
                            .enableComplexMapKeySerialization()//支持Map的key为复杂对象的形式  
                            .serializeNulls() //智能null  
                            .setPrettyPrinting()// 调教格式  
                            .disableHtmlEscaping() //默认是GSON把HTML 转义的
                            .create();  

    Gson的基本用法:

    注:JavaBean:

    @NoArgsConstructor
    @AllArgsConstructor
    @Setter
    @Getter
    @ToString
    @Builder
    public class PersonJson {
        private String name;
        private Integer age;
        private String hobby;
    }
    //hobby是在后面的例子中添加的。要么就name,age两个属性,要么就三个。
    //上面的注解是lombok的注解,起到简化Bean类的作用。

    Gson提供了public String toJson(Objcet obj)方法,可以将对象转化为json字符串。

    JavaBean转化为json字符串

    public class IndexTest {
        PersonJson person;
        @Before
        public void prepare() {
            person = new PersonJson("栗霖",18);
        }
    
        @Test
        public void index() {
            Gson gson = new Gson();
            System.out.println(gson.toJson(person));
            System.out.println("---------------");
            Gson gson1 = new GsonBuilder().create();
            System.out.println(gson1.toJson(person));
        }
    }

    结果:

    List Map 转化为json字符串

    public class IndexTest {
        PersonJson person;
        List<PersonJson> list = new ArrayList<>();
        Map<String,PersonJson> map = new HashMap<>();
        @Before
        public void prepare() {
            person = new PersonJson("栗霖",18);
            list.add(person);
            map.put(person.getName(),person);
        }
    
        @Test
        public void index() {
            Gson gson = new Gson();
            System.out.println("---->List convert json" + gson.toJson(list));
            System.out.println("------------------------");
            System.out.println("---->map convert json" + gson.toJson(map));
        }
    }

    结果:

     

    Gson提供了public T fromJson(String jsonStr,T.class)方法,可以将json字符串转化为Java对象 

    json字符串转化为JavaBean

    public class SecondTest {
        @Test
        public void index() {
            String jsonStr = "{"name":"栗霖","age":"18"}";
            Gson gson = new GsonBuilder().create();
            PersonJson p = gson.fromJson(jsonStr,PersonJson.class);
            System.out.println("---->jsonStr convert javaBean " + p.getName() + " " + p.getAge());
        }
    }

    结果:

    json字符串转化为list集合

    public class SecondTest {
        @Test
        public void index() {
            String listJsonStr = "[{"name":"栗霖","age":"18"},{"name":"栗霖之雨","age":"18"}]";
            Gson gson = new GsonBuilder().create();
            List<PersonJson> list = gson.fromJson(listJsonStr,new TypeToken<ArrayList<PersonJson>>(){}.getType());
            System.out.println("---->listJsonStr convert List " + list);
        }
    }

    结果:

    json的抽象基类JsonElemetn:

    JsonNull其实就是Null字段

    public class SecondTest {
        @Test
        public void index() {
            //JsonNull jsonNull = new JsonNull();该方法已经过时
            JsonNull jsonNull = JsonNull.INSTANCE;
            System.out.println("---->jsonNull  " + jsonNull);
        }
    }

    结果:

    jsonPrimitive可以帮助我们获取带转义字符的字符串。这个就不写了。感觉没啥用到。

    创建JsonObject:

      可以通过addProperty(String,Object)向JsonObject添加属性,跟hashmap类似。

    public class SecondTest {
        @Test
        public void index() {
            JsonObject jsonObject = new JsonObject();
            jsonObject.addProperty("name","栗霖");
            jsonObject.addProperty("age",18);
            System.out.println("---->create jsonObject  " + jsonObject);
        }
    }

    结果:

    创建JsonArray

    public class SecondTest {
        @Test
        public void index() {
            JsonArray jsonArray = new JsonArray();
            jsonArray.add("a");
            jsonArray.add("b");
            jsonArray.add("c");
            jsonArray.add("d");
            System.out.println("---->create jsonArray: " + jsonArray);
        }
    }

    结果:

    JsonObject嵌套数组或者说JsonObject嵌套JsonArray

    public class SecondTest {
        @Test
        public void index() {
            JsonObject jsonObject = new JsonObject();
            jsonObject.addProperty("name","栗霖");
            jsonObject.addProperty("age",18);
            JsonArray jsonArray = new JsonArray();
            jsonArray.add("是码农");
            jsonArray.add("以前喜欢玩游戏");
            jsonArray.add("现在只敢小心积累");
            jsonArray.add("只怕突然白了头");
            jsonObject.add("status",jsonArray);
            System.out.println("---->create jsonArray: " + jsonObject);
        }
    }

    结果:


     

    Gson注解

    重命名注解:@SerializedName

    当你调用其他服务时,他们返回的json KEY值与你的Bean属性名称不对应怎么办?

    这时候就需要@SerializedName啦。他可以帮助你解决这个问题!

    实体类:

    @NoArgsConstructor
    @AllArgsConstructor
    @Setter
    @Getter
    @ToString
    @Builder
    public class PersonJson {
        private String name;
        private Integer age;
        //这里只是随便举个例子,千万不要用中文!!!
        @SerializedName(value = "爱好")
        private String hobby;
    }

    示例:

    public class SecondTest {
        JsonObject jsonObject;
        JsonArray jsonArray;
    
        @Before
        public void index() {
            jsonObject = new JsonObject();
            jsonObject.addProperty("name","栗霖");
            jsonObject.addProperty("age",18);
            jsonArray = new JsonArray();
            jsonArray.add("是码农");
            jsonArray.add("以前喜欢玩游戏");
            jsonArray.add("现在只敢小心积累");
            jsonArray.add("只怕突然白了头");
            jsonObject.addProperty("爱好",jsonArray.toString());
        }
    
        @Test
        public void formal() {
            Gson gson = new GsonBuilder().create();
            PersonJson personJson = gson.fromJson(jsonObject.toString(),PersonJson.class);
            System.out.println("---->String: " + personJson);
        }
    }

    结果:

    @serializedName

    除了value属性外,还可以使用alternate属性,这个值可以替换前面的值,将传入的json进行修改。

    注:value的值不能出现在alternate中,alternate是备选字段。

    @SerializedName(value = "hobby", alternate = {"interest","be fond of"})

    过滤注解@Expose

    注:默认是既可以序列化,也可以反序列化。一定要配合GsonBuilder一起使用

      该注解是加在JavaBean的属性上使用的。

      配合这个使用哦Gson gson = new GsonBuilder().excludeFieldWithoutExposeAnnotation().create();

    有四种使用方式:

      1)不使用@Expose注解等同于@Expose(deserialize = false, serialize = false)不做任何解析

      2)@Expose(deserialize = true, serialize = false)只解析使用,可以反序列化,不可以序列化。

      3)@Expose(deserialize = false, serialize = true)可以序列化,不可以反序列化。

      4)@Expose(deserialize = false, serialize = true)既可以序列化,也可以反序列化。

    注:这里的序列化指:将对象转化为json字符串。反序列化指:将json字符串转化成对象。

    版本控制注解@Since(float v)

    结合GsonBuilder().serVersion(n)使用。当n>=v时,才会解析。

    注:也是加在JavaBean属性上使用的。

    版本控制注解@Util(float v)

    与@Since相反,这次是n<v时才能够解析。

    使用TypeAdapter来实现序列化与反序列化。

    使用TypeAdapter来序列化和反序列化

    代码:

    public class FiveTest {
        @Test
        public void index() {
            Gson gson = new GsonBuilder().create();
            TypeAdapter<PersonJson> typeAdapter = gson.getAdapter(PersonJson.class);
            String json = "{"name":"栗霖","age":"18","hobby":"我很是很喜欢FromSoftWare的。大爱宫崎英高,赞美太阳"}";
            PersonJson p = new PersonJson("栗霖",18,"混系列忠实粉丝");
    
            System.out.println("---->序列化:是将对象转化为字符串 : " + typeAdapter.toJson(p));
            try {
                System.out.println("---->反序列化:是将字符串转化为对象 : "+ typeAdapter.fromJson(json));
            }catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    结果:

     

    Gson的容错机制

    为什么容错:

      如果Bean中定义的是int,但是返回的json对应的是一个""空字串怎么办?这就依赖到了Gson的容错机制。

    1)创建宽松Gson

    遇到问题,停止解析,以防止报错,功能相对较弱。

    Gson gson = new GsonBuilder()
                            .setLenient()//宽松
                            .create();

    2)自定义TypeAdapter

    该方法更倾向于整体防止出现异常。

    public class ThirdTest {
    
        public static class PersonTypeAdapter extends TypeAdapter<PersonJson> {
            @Override
            public void write(JsonWriter jsonWriter, PersonJson personJson) throws IOException {
                jsonWriter.beginObject();
                jsonWriter.name("name").value(personJson.getName());
                jsonWriter.name("age").value(personJson.getAge());
                jsonWriter.name("hobby").value(personJson.getHobby());
                jsonWriter.endObject();
            }
    
            @Override
            public PersonJson read(JsonReader jsonReader) throws IOException {
                PersonJson personJson = new PersonJson();
                jsonReader.beginObject();
                while (jsonReader.hasNext()) {
                    switch (jsonReader.nextName()) {
                        case "name":
                            personJson.setName(jsonReader.nextString());
                            break;
                        case "age":
                            try {
                                personJson.setAge(Integer.valueOf(jsonReader.nextString()));
                            } catch (Exception e) {
                            }
                            break;
                        case "hobby":
                            personJson.setHobby(jsonReader.nextString());
                    }
                }
                jsonReader.endObject();
                return personJson;
            }
        }
    
        @Test
        public void index() {
            Gson gson = new Gson();
    
            String json = "{"name":"栗霖","age":"","hobby":"篮球吧,读书吧,steam吧"}";
    
            System.out.println("----> " + json );
    
            try {
                PersonJson p1 = gson.fromJson(json,PersonJson.class);
                System.out.println("---->默认解析 " + p1);
            }catch (Exception e) {
                System.out.println("---->异常解析,这里json字符串缺失了age的值,真的是怕一转眼就白了头啊" +e);
            }
    
            Gson gson1 = new GsonBuilder().registerTypeAdapter(PersonJson.class,new PersonTypeAdapter()).create();
    
            try {
                PersonJson p2 = gson1.fromJson(json,PersonJson.class);
                System.out.println("---->自定义Adapter 默认解析 "+p2);
            }catch (Exception e) {
                System.out.println("---->自定义adapter 异常解析" + e);
            }
    
            try {
                PersonTypeAdapter personTypeAdapter = new PersonTypeAdapter();
                PersonJson p3 = personTypeAdapter.fromJson(json);
                System.out.println("---->自定义Adapter 默认解析 " + p3);
            }catch (Exception e){
                System.out.println("---->自定义Adapter 异常解析 " +e);
            }
        }
    }

    结果:

    3)使用注解jsonAdapter,其实质也是自定义Adapter

      该方法更倾向于某一个属性的保护。

    实体类:

    public class PersonJson {
        private String name;
        @JsonAdapter(IntegerTypeAdapter.class)
        private Integer age;
        private String hobby;
    }

    Adapter:

    public class IntegerTypeAdapter extends TypeAdapter<Integer>{
        @Override
        public void write(JsonWriter jsonWriter, Integer integer) throws IOException {
            jsonWriter.value(integer);
        }
    
        @Override
        public Integer read(JsonReader jsonReader) throws IOException {
            int i = 0;
            try {
                i = Integer.valueOf(jsonReader.nextString());
            }catch (Exception e){}
            return i;
        }
    }

    测试类:

    public class FourTest {
    
        @Test
        public void index() {
            Gson gson = new Gson();
            String json = "{"name":"栗霖","age":"","hobby":"篮球吧,读书吧,steam吧"}";
    
            try {
                PersonJson p1 = gson.fromJson(json,PersonJson.class);
                System.out.println("---->默认解析 " + p1);
            }catch (Exception e) {
                System.out.println("---->异常解析,这里json字符串缺失了age的值,真的是怕一转眼就白了头啊" +e);
            }
    
            try {
                PersonJson p2 = gson.fromJson(json,PersonJson.class);
                System.out.println("---->默认解析 " + p2);
            }catch (Exception e) {
                System.out.println("---->异常解析" + e);
            }
        }
    }

    结果:

     本文参考:http://blog.csdn.net/axuanqq/article/details/51441590,学习整理。如果你觉得喜欢不妨点个赞,如果你觉得哪里有问题欢迎留言讨论。

  • 相关阅读:
    jdbc代码
    openwrt vsftp
    openwrt 配置samba && ubuntu 配置samba
    如何学习开源项目
    Makefile 笔记
    Samba 学习笔记
    quilt-补丁工具
    to-do-list
    新增feeds模块
    linux命令
  • 原文地址:https://www.cnblogs.com/lilinzhiyu/p/8269682.html
Copyright © 2011-2022 走看看