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,学习整理。如果你觉得喜欢不妨点个赞,如果你觉得哪里有问题欢迎留言讨论。

原文地址:https://www.cnblogs.com/lilinzhiyu/p/8269682.html

时间: 2024-10-29 18:59:24

Gson的学习与使用的相关文章

Json与Java对象互转之Gson学习

Json与Java对象互转之Gson学习 请尊重他人的劳动成果,转载请注明出处:Json与Java对象互转之Gson学习         我曾在<XML,Object,Json转换之浅析Xstream的使用>一文中介绍过使用XStream进行XML,Object,Json之间的转换,虽然XStream内置了对Json的支持,但是效果不是特别好,毕竟XStream重点不在Json.下面就介绍另外一种工具.           Gson(又称Google Gson)是Google公司发布的一个开放

Retrofit2.0通俗易懂的学习姿势,Retrofit2.0 + OkHttp3 + Gson + RxJava

Retrofit2.0通俗易懂的学习姿势,Retrofit2.0 + OkHttp3 + Gson + RxJava Retrofit,因为其简单与出色的性能,也是受到很多人的青睐,但是他和以往的通信框架还是有点区别,不过放心,因为他本身还是挺简单的,所有我相信你看完这篇文章,对基本的请求是没什么问题的,其实现在网上这样的文章也有很多了,好了,那我们直接开车吧! 一.相关资料 Github:https://github.com/square/retrofit 官网文档:http://square

GSON使用的学习笔记,进阶篇(三)

本篇笔记内容比较杂乱,没有专门去整理. TypeAdapter 现在轮到TypeAdapter类上场,但考虑到gson默认行为已足够强大,加上项目实践中应用json时场景不会太复杂,所以一般不需要自定义TypeAdapter.TypeAdapter优点是集成了JsonWriter和JsonReader两个类,定义了一套与gson框架交互的良好接口,同时便于管理编码和解码的实现代码,不至于太零碎.因而在了解JsonReader和JsonWriter的使用方法之后,自定义TypeAdapter类来完

GSON学习笔记之初识GSON

引用"JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,採用全然独立于语言的文本格式.为Web应用开发提供了一种理想的数据交换格式. " 曾经手机端与server数据交互的时候用过xml格式,后来又用了JSON格式,无论是server生成json数据,还是手机端解析json数据,尽管用到一些json库,但都比較繁琐.近期从一些项目中发现了Google的gson,就開始学习使用.经过比較,发现gson与其它json库最大的不同是.gson直接使用

GSON源码LinkedTreeMap学习

在学习GSON的过程中,发现了GSON的基础数据类型LinkedTreeMap,因此展开学习. private final LinkedTreeMap<String, JsonElement> members = new LinkedTreeMap<String, JsonElement>(); LinkedTreeMap,一切如此的熟悉,在jdk中有LinkedMap有TreeMap有TreeMap,这个LinkedTreeMap是个什么,顾名思义,这应该是一个连续的且有序的集合

gson学习以及进阶文章推荐

Json转换利器Gson之实例一-简单对象转化和带泛型的List转化 (http://blog.csdn.net/lk_blog/article/details/7685169)Json转换利器Gson之实例二-Gson注解和GsonBuilder (http://blog.csdn.net/lk_blog/article/details/7685190)Json转换利器Gson之实例三-Map处理(上) (http://blog.csdn.net/lk_blog/article/details

Google中Gson的使用解析json数据-------学习篇

之前写过一篇Gson解析json数据的基本应用,这里不多说,直接上例子. 有兴趣的可以先阅读下之前那篇,这里附上链接: http://www.cnblogs.com/Ant-soldier/p/6322456.html // json跟set集合之间的转换        String str = "[{'name':'zhangsan','age':20},{'name':'lisi','age':33}]";        Gson gson = new Gson();      

JavaFX基础学习之OkHttp/Gson

导入jar包,使用OkHttp/Okio/Gson请求解析 package application; import java.io.IOException; import java.net.URL; import java.util.ResourceBundle; import com.google.gson.Gson; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.Initializab

【幻化万千戏红尘】qianfengDay29-Json解析、Gson解析、FASTJSON解析基础学习:

课程回顾: XML:可扩展的标记语言跨平台.跨网络.跨编程语言描述数据作用:1.传输数据2.配置文件3.Android的布局文件 解析XML:1.SAX2.PULL 创建类 今日内容:JSON:JavaScript Object Notation就是符合一定格式的字符串是轻量级,数据交互的格式目前互联网中使用范围最为广泛的数据交互的格式跨平台.跨网络.跨编程语言JSON的规则:{}---->对象,内部只能是属性组成[]---->数组,内部只能是元素组成""---->属