美文网首页
Gson解析JSON

Gson解析JSON

作者: 远方的橄榄树 | 来源:发表于2019-11-14 16:12 被阅读0次

1. 开始

构建maven项目

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.smallbear</groupId>
    <artifactId>gson-demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.8</version>
            <scope>provided</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.5</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/junit/junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.8.1</version>
        </dependency>
    </dependencies>
</project>

实体类

@Data
@Accessors(chain = true)
public class Person {

    private String name;

    private Boolean isAdult;

    private Integer age;

    @SerializedName("email_or_phone")
    private String emailOTelephone;

    private Job job;

    private List<Pet> pets;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Job {

    private String name;

    private BigDecimal salary;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Pet {

    private String name;

    private String type;

    private Integer age;
}
@Data
@Accessors(chain = true)
public class Role {

    private String name;

    private String username;

    private Date createTime;

    private BigDecimal money;

    private Integer level;
}

2. gson解析对象

    /**
     * Gson解析对象 object -> json
     */
    @Test
    public void test01() {
        Gson gson = new Gson();
        Job job = new Job("teacher", BigDecimal.valueOf(8000.0));
        System.out.println(gson.toJson(job)); // {"name":"teacher","salary":8000.0}
    }
    /**
     * 属性重命名 @SerializedName
     *在pojo字段上标注@SerializedName可以设置输出json的字段的属性名
     */
    @Test
    public void test02() {
        Gson gson = new Gson();
        Person person = new Person()
                .setName("小明")
                .setIsAdult(true)
                .setAge(23)
                .setEmailOTelephone("12345678.qq.com");
        System.out.println(gson.toJson(person));
        // {"name":"小明","isAdult":true,"age":23,"email_or_phone":"12345678.qq.com"}
        //gson默认不解析值为null的字段
    }

3. gson反序列化

    /**
     * Gson反序列化 json -> object
     */
    @Test
    public void test03() {
        Gson gson = new Gson();
        String s = "{\"name\":\"小明\",\"isAdult\":false,\"age\":14,\"job\":{\"name\":\"teacher\",\"salary\":8000.0},\"pets\":[{\"name\":\"jack\",\"type\":\"mouse\",\"age\":3},{\"name\":\"tom\",\"type\":\"cat\",\"age\":4}]}";
        Person person =gson.fromJson(s, Person.class);
        System.out.println(person);
        // Person(name=小明, isAdult=false, age=14, emailOTelephone=null, job=Job(name=teacher, salary=8000.0), pets=[Pet(name=jack, type=mouse, age=3), Pet(name=tom, type=cat, age=4)])
    }
    /**
     * Gson解析泛型
     */
    @Test
    public void test04() {
        Gson gson = new Gson();
        String s = "[{\"name\":\"jack\",\"type\":\"mouse\",\"age\":3},{\"name\":\"tom\",\"type\":\"cat\",\"age\":4}]";
        List<Pet> list = gson.fromJson(s, new TypeToken<List<Pet>>() {}.getType());
        System.out.println(list);
        // [Pet(name=jack, type=mouse, age=3), Pet(name=tom, type=cat, age=4)]
    }

4、Gson高级使用

1、GsonBuilder的使用

    /**
     * 使用GsonBuilder配置解析方式
     */
    @Test
    public void test05() {
        Gson gson = new GsonBuilder()
                .serializeNulls() // 序列化null
                .setDateFormat("yyyy-MM-dd HH:mm:ss") // 格式化时间
                .setPrettyPrinting() // 格式化输出
                .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE) // 字段首字母大写
                .create();

        Role role = new Role()
                .setName("魔导师")
                .setUsername("tom")
                .setCreateTime(new Date())
                .setMoney(BigDecimal.valueOf(111111));
        System.out.println(gson.toJson(role));
    }
/*
{
  "Name": "魔导师",
  "Username": "tom",
  "CreateTime": "2019-11-13 22:05:38",
  "Money": 111111,
  "Level": null
}
*/

2、@Expose注解设置字段是否解析

@Data
@Accessors(chain = true)
public class Book {

    /**
     * 被@Expose标记的字段会参与序列化和反序列化
     */
    @Expose
    private String name;

    private String EnglishName;

    /**
     * serialize和deserialize默认为true,即会参与序列化和反序列化
     * author字段会被序列化,但不会反序列化
     */
    @Expose(deserialize = false)
    private String author;

    @Expose
    private BigDecimal price;
}
    /**
     * 注解@Expose
     */
    @Test
    public void test06() {
        Gson gson = new GsonBuilder()
                .excludeFieldsWithoutExposeAnnotation()
                .create();
        Book book = new Book()
                .setName("Spring实战")
                .setEnglishName("Spring In Action")
                .setAuthor("Craig Walls")
                .setPrice(BigDecimal.valueOf(89.00));

        String json = gson.toJson(book);
        System.out.println(json);

        Book b = gson.fromJson(json, Book.class);
        System.out.println(b);
    }
    /*
    {"name":"Spring实战","author":"Craig Walls","price":89.0}
    Book(name=Spring实战, EnglishName=null, author=null, price=89.0)
     */

注意:要是@Expose注解起作用一定要采用GsonBuilder创建Gson并且调用了excludeFieldsWithoutExposeAnnotation()才起作用。

  1. 使用TypeAdapter自定义解析方式
@Data
@Accessors(chain = true)
public class User {

    private String name;

    private Integer age;

    private String[] hobbies;
}
public class UserTypeAdapter extends TypeAdapter<User> {

    /**
     * 序列化
     */
    public void write(JsonWriter writer, User user) throws IOException {
        writer.beginObject();
        writer.name("name").value(user.getName());
        writer.name("age").value(user.getAge());
        writer.name("hobbies").value(StringUtils.join(user.getHobbies(), ";"));
        writer.endObject();
    }

    /**
     * 反序列化
     */
    public User read(JsonReader reader) throws IOException {
        final User user = new User();

        reader.beginObject();
        while (reader.hasNext()) {
            String s = reader.nextName();
            if ("name".equals(s)) {
                user.setName(reader.nextString());

            } else if ("age".equals(s)) {
                user.setAge(reader.nextInt());

            } else if ("hobbies".equals(s)) {
                user.setHobbies(reader.nextString().split(";"));
            }
        }
        reader.endObject();
        return user;
    }
}

测试

/**
     *
     */
    @org.junit.Test
    public void test08() {
        Gson gson = new GsonBuilder()
                .registerTypeAdapter(User.class, new UserTypeAdapter()) // 注册自定义的类型适配器
                .setPrettyPrinting()
                .create();

        User user = new User()
                .setName("王八")
                .setAge(13)
                .setHobbies(new String[] {"游泳", "跑步", "健身"});
        System.out.println(gson.toJson(user));

        String s = "{\"name\":\"王八\",\"age\":13,\"hobbies\":\"游泳;跑步;健身\"}";
        String s2 = "{\"name\":\"李四\",\"age\":53}";
        System.out.println(gson.fromJson(s, User.class));
        System.out.println(gson.fromJson(s2, User.class));
    }
/*
{
  "name": "王八",
  "age": 13,
  "hobbies": "游泳;跑步;健身"
}
User(name=王八, age=13, hobbies=[游泳, 跑步, 健身])
User(name=李四, age=53, hobbies=null)
*/
  1. TypeAdapter解析复杂对象
@Data
@Accessors(chain = true)
public class Movie {

    private String name;

    private Double score;

    private List<Actor> actors;

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    static class Actor {

        private Integer id;

        private String name;
    }
}
public class MovieTypeAdapter extends TypeAdapter<Movie> {

    @Override
    public void write(JsonWriter writer, Movie movie) throws IOException {
        writer.beginObject();
        writer.name("name").value(movie.getName());
        writer.name("score").value(movie.getScore());
        writer.name("actors").beginArray();

        if (movie.getActors() != null) {
            for (Movie.Actor actor : movie.getActors()) {
                writer.beginObject();
                writer.name("id").value(actor.getId());
                writer.name("name").value(actor.getName());
                writer.endObject();
            }
        }

        writer.endArray();
        writer.endObject();
    }

    @Override
    public Movie read(JsonReader reader) throws IOException {
        final Movie movie = new Movie();

        reader.beginObject();
        while (reader.hasNext()) {
            String s = reader.nextName();

            if ("name".equals(s)) {
                movie.setName(reader.nextString());
            } else if ("score".equals(s)) {
                movie.setScore(reader.nextDouble());
            } else if ("actors".equals(s)) {
                reader.beginArray();
                final List<Movie.Actor> actors = new ArrayList<>();

                while (reader.hasNext()) {
                    reader.beginObject();
                    final Movie.Actor actor = new Movie.Actor();

                    while (reader.hasNext()) {
                        String s2 = reader.nextName();
                        if ("id".equals(s2)) {
                            actor.setId(reader.nextInt());
                        } else if ("name".equals(s2)) {
                            actor.setName(reader.nextString());
                        }
                    }
                    actors.add(actor);
                    reader.endObject();
                }
                movie.setActors(actors);
                reader.endArray();
            }
        }
        reader.endObject();
        return movie;
    }
}

测试

   @org.junit.Test
    public void test09() {
        Gson gson = new GsonBuilder()
                .registerTypeAdapter(Movie.class, new MovieTypeAdapter())
//                .setPrettyPrinting()
                .create();

        List<Movie.Actor> actors = new ArrayList<>();
         actors.add(new Movie.Actor(1, "贝尔"));
         actors.add(new Movie.Actor(2, "希斯.莱杰"));
         Movie movie = new Movie()
                 .setName("黑暗骑士")
                 .setScore(9.2)
                 .setActors(actors);

         System.out.println(gson.toJson(movie));

        Movie movie2 = new Movie()
                .setName("千与千寻")
                .setScore(9.1);
        System.out.println(gson.toJson(movie2));

        String s = "{\"name\":\"黑暗骑士\",\"score\":9.2,\"actors\":[{\"id\":1,\"name\":\"贝尔\"},{\"id\":2,\"name\":\"希斯.莱杰\"}]}";
        String s2 = "{\"name\":\"千与千寻\",\"score\":9.1,\"actors\":[]}";
        System.out.println(gson.fromJson(s, Movie.class));
        System.out.println(gson.fromJson(s2, Movie.class));
    }
/*
{"name":"黑暗骑士","score":9.2,"actors":[{"id":1,"name":"贝尔"},{"id":2,"name":"希斯.莱杰"}]}
{"name":"千与千寻","score":9.1,"actors":[]}
Movie(name=黑暗骑士, score=9.2, actors=[Movie.Actor(id=1, name=贝尔), Movie.Actor(id=2, name=希斯.莱杰)])
Movie(name=千与千寻, score=9.1, actors=[])
*/
  1. GsonBuilder方法解释
  • setFieldNamingPolicy 设置序列字段的命名策略
    UPPER_CAMEL_CASE(首字母大写)
    UPPER_CAMEL_CASE_WITH_SPACES (首字母大写并且驼峰转空格)
    LOWER_CASE_WITH_UNDERSCORES (大写转小写,驼峰转"_")
    LOWER_CASE_WITH_DASHES
    LOWER_CASE_WITH_DOTS
  • addDeserializationExclusionStrategy 设置反序列化时字段采用策略ExclusionStrategy,如反序列化时不要某字段,当然可以采用@Expore代替。
  • excludeFieldsWithoutExposeAnnotation 设置没有@Expore则不序列化和反序列化
    addSerializationExclusionStrategy 设置序列化时字段采用策略,如序列化时不要某字段,当然可以采用@Expore代替。
  • registerTypeAdapter 为某特定对象设置固定的序列和反序列方式,实现JsonSerializer和JsonDeserializer接口
  • setFieldNamingStrategy 设置字段序列和反序列时名称显示,也可以通过@Serializer代替
  • setPrettyPrinting 设置gson转换后的字符串为一个比较好看的字符串
  • setDateFormat 设置解析时的日期格式

参考链接:
Java 中 Gson的使用
Gson高级使用和GsonBuilder设置
Gson全解析(上)-Gson基础
Gson全解析(中)-TypeAdapter的使用
Gson全解析(下)-Gson性能分析

相关文章

  • GSON 解析 JSON

    GSON JSON 介绍 Gson 下载 Gson 解析 和 格式化Gson 格式化Gson 解析 解析asset...

  • Android Gson官方推荐的json解析方式

    导航 XML的三种解析方式 json全面解析和使用 Gson官方推荐的json解析方式 Gson Gson解析是g...

  • 2018-01-11

    Gson解析复杂json数据常用的两种解析方式 Gson gson = new Gson(); 1.gson.fr...

  • Json解析(使用Gson)

    Json的解析成 java 对象 Gson gson = new Gson(); // 将json 转化成 j...

  • Gson序列化那些事

    Android开发中会经常解析json,使用retrofit框架常用gson解析json。Gson有一定的容错机制...

  • Json解析方式

    1.传统的JSON解析 1.1 生成Json 1.2 解析Json 2.Gson解析Json 2.1生成Json ...

  • 第七周随笔(3)--JSON

    关于JSON的写法: 常用的解析JSON的开源代码: GSON fastJSON······· GSON的用法: ...

  • Gson的使用

    为什么转用Gson了,FastJSON bug实在是太多了! 依赖 pojo 谷歌Gson解析json json转...

  • 使用Gson的一些感悟——解析复杂json

    使用Gson的一些感悟——解析复杂json 将json解析为泛型对象时,发现Gson有种很特别的写法,因此学习了下...

  • Gson解析josn

    gson的Maven依赖:2019年9月5日11:23:12最新 gson解析json对象 对象参数: 解析代码 ...

网友评论

      本文标题:Gson解析JSON

      本文链接:https://www.haomeiwen.com/subject/tpbkictx.html