几种常用JSON解析框架的使用操作

几种常用JSON解析框架的使用操作

  • JSON概述
  • fastjson的使用
    • 添加依赖
    • 常用API
    • JSON解析
    • JSON封装
  • gson的使用
    • 概述
    • 添加依赖
    • toJson()
    • fromJson()
    • GsonBuilder
    • JSON对象数据写入文件
    • 将JSON数据读取到Java数组
    • 从URL读取JSON
    • 打印
    • 序列化空值
    • 使用@Expose排除字段
  • jackson的使用
    • 概述
    • 添加依赖
    • ObjectMapper对象映射器
    • 对象转JSON
    • JSON转对象
    • JSON转List
    • JSON转Map
    • 字段忽略
    • 日期格式化
    • Jackson常用注解

JSON概述

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,相比xml数据交换格式来说,因为解析xml比较的复杂且需要编写大段的代码,所以客户端和服务器的数据交换格式往往通过JSON来进行交换。

json简单说就是javascript中的对象和数组,所以这两种结构就是对象和数组两种结构,通过这两种结构可以表示各种复杂的结构。

几种常用JSON解析框架的使用操作_第1张图片

常用JSON解析框架

fastjson(阿里)

gson(谷歌)

jackson(SpringMVC自带)

XML与JSON的区别

Xml是重量级数据交换格式,占宽带比较大。

JSON是轻量级交换格式,占宽带小。

fastjson的使用

添加依赖

添加对fastjson的Maven依赖

<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.76</version>
</dependency>

常用API

    //把JSON文本parse为JSONObject或者JSONArray
    public static final Object parse(String text);
    //把JSON文本parse成JSONObject
    public static final JSONObject parseObject(String text);
    //把JSON文本parse为JavaBean
    public static final <T> T parseObject(String text, Class<T> clazz);
    //把JSON文本parse成JSONArray
    public static final JSONArray parseArray(String text);
    //把JSON文本parse成JavaBean集合
    public static final <T> List<T> parseArray(String text, Class<T> clazz);
    //将JavaBean序列化为JSON文本
    public static final String toJSONString(Object object);
    //将JavaBean序列化为带格式的JSON文本
    public static final String toJSONString(Object object, boolean prettyFormat);
    //将JavaBean转换为JSONObject或者JSONArray。
    public static final Object toJSON(Object javaObject);

JSON解析

  public static void main(String[] args) {
        String userJson = "{\"users\":[{\"name\":\"小白\",\"age\":\"12\"},{\"name\":\"大白\",\"age\":\"22\"}]}";

        //将json字符串转换为jsonObject
        JSONObject parseObject = JSON.parseObject(userJson);
        // 获取json数组对象
        JSONArray usersArray = parseObject.getJSONArray("users");
        for (Object object : usersArray) {
            JSONObject jsonObejct = (JSONObject) object;
            String name = jsonObejct.getString("name");
            String age = jsonObejct.getString("age");
            System.out.println(name + "----" + age);
        }
    }

JSON封装

	public static void main(String[] args) {
		JSONObject jsonObject = new JSONObject();
		JSONArray usersArray = new JSONArray();
		
		JSONObject user1 = new JSONObject();
		user1.put("name", "小白");
		user1.put("age", "12");
		usersArray.add(user1);
		
		JSONObject user2 = new JSONObject();
		user2.put("name", "大白");
		user2.put("age", "22");
		usersArray.add(user2);
		
		jsonObject.put("users", usersArray);
		System.out.println(jsonObject.toJSONString());
	}
{"users":[{"age":"12","name":"小白"},{"age":"22","name":"大白"}]}

gson的使用

概述

Gson是Java序列化/反序列化库,用于将 Java 对象转换为JSON并返回。 Gson由Google创建,供内部使用,后来开源。

Gson具有三种API:数据绑定 API、树模型 API、流 API

数据绑定 API 使用属性访问器将JSON与POJO之间进行转换。 Gson使用数据类型适配器处理 JSON 数据。 它类似于XML JAXB解析器。

树模型 API创建JSON 文档的内存树表示。 它构建JsonElements的树。 它类似于XML DOM解析器。

流 API是一种低级 API,它使用JsonReader和JsonWriter作为离散记号读取和写入 JSON 内容。 这些类将数据读取为JsonTokens。 该 API 具有最低的开销,并且在读/写操作中速度很快。 它类似于 XML 的 Stax 解析器

添加依赖

添加对Gson的Maven依赖

		<dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.9.0</version>
        </dependency>

toJson()

Gson是使用Gson库的主要类

toJson()方法将指定的对象序列化为其等效的JSON表示形式

    public static void main(String[] args) {
        Map<Integer, String> map = new HashMap<>();
        map.put(1, "a");
        map.put(2, "b");
        map.put(3, "c");

        Gson gson = new Gson();

        String output = gson.toJson(map);

        System.out.println(output);
    }
{"1":"a","2":"b","3":"c"}

fromJson()

fromJson()方法将JSON读取到Java对象中

    public static void main(String[] args) {
        String json_string = "{\"username\":\"Jack\", \"age\": \"20\"}";

        Gson gson = new Gson();
        
        User user = gson.fromJson(json_string, User.class);

        System.out.println(user);
    }

    @ToString
    @AllArgsConstructor
    class User {
        private String username;
        private String age;
    }

GsonBuilder

GsonBuilder可使用各种配置设置构建Gson。GsonBuilder遵循构建器模式,通常通过首先调用各种配置方法来设置所需的选项,最后调用create()来使用它。

    public static void main(String[] args) throws UnsupportedEncodingException {
        try (PrintStream prs = new PrintStream(System.out, true, "UTF8")) {
            Gson gson = new GsonBuilder()
                    // 配置Gson在序列化和反序列化期间将特定的命名策略应用于对象的字段。
                    // 字段命名策略设置为FieldNamingPolicy.UPPER_CAMEL_CASE: 确保Java字段名称的第一个“字母”在序列化为其JSON形式时大写
                    .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)
                    .create();

            User user = new User("Jack", 20);
            gson.toJson(user, prs);
        }
    }

    @ToString
    @AllArgsConstructor
    static
    class User {
        private String username;
        private Integer age;
    }
{"Username":"Jack","Age":20}

JSON对象数据写入文件

将JSON数据写入一个json文件。

    public static void main(String[] args) throws IOException {
        String filePath = "src/main/resources/users.json";

        try (FileOutputStream fos = new FileOutputStream(filePath);
             OutputStreamWriter isr = new OutputStreamWriter(fos, StandardCharsets.UTF_8)) {

            Gson gson = new Gson();

            User user1 = new User("Jack", 23);
            User user2 = new User("Jon", 22);
            User user3 = new User("Tom", 33);

            List<User> users = new ArrayList<>();
            users.add(user1);
            users.add(user2);
            users.add(user3);

            gson.toJson(users, isr);
    

将JSON数据读取到Java数组

将json文件中的JSON数据读取到数组中,并打印到控制台。

    public static void main(String[] args) throws IOException {
        String filePath = "src/main/resources/users.json";
        Path path = new File(filePath).toPath();

        try (Reader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {
            User[] users = new Gson().fromJson(reader, User[].class);
            Arrays.stream(users).forEach(e -> System.out.println(e));
        }
    }
ApplicationTests.User(username=Jack, age=23)
ApplicationTests.User(username=Jon, age=22)
ApplicationTests.User(username=Tom, age=33)

从URL读取JSON

   public static void main(String[] args) throws IOException {
        String url = "xxx";

        try (InputStream is = new URL(url).openStream();
             Reader reader = new InputStreamReader(is, StandardCharsets.UTF_8)) {

            Gson gson = new Gson();
            User user = gson.fromJson(reader, User.class);

            System.out.println(user);
        }
    }

打印

Gson 有两种输出模式:紧凑和漂亮。通过setPrettyPrinting()方法设置漂亮的打印模式。

    public static void main(String[] args) {
        Gson gson1 = new GsonBuilder().create();
        Gson gson2 = new GsonBuilder().setPrettyPrinting().create();

        Map<Integer, String> map = new HashMap<>();
        map.put(1, "a");
        map.put(2, "b");
        map.put(3, "c");

        gson1.toJson(map, System.out);
        System.out.println("");
        gson2.toJson(map, System.out);
    }
{"1":"a","2":"b","3":"c"}
{
  "1": "a",
  "2": "b",
  "3": "c"
}

序列化空值

默认情况下,Gson 不会将具有空值的字段序列化为 JSON。 如果 Java 对象中的字段为null,则 Gson 会将其排除。 我们可以使用serializeNulls()方法强制 Gson 通过 GsonBuilder 序列化null值。

    public static void main(String[] args) {
        Gson gson1 = new GsonBuilder().create();
        Gson gson2 = new GsonBuilder().serializeNulls().create();

        User user = new User("Jack", null);

        System.out.println(gson1.toJson(user));
        System.out.println(gson2.toJson(user));
    }
{"username":"Jack"}
{"username":"Jack","age":null}

使用@Expose排除字段

@Expose注解指定那些成员公开以进行JSON序列化或反序列化

@Expose注解可以采用两个布尔参数:serialize和deserialize进行控制
 
必须使用excludeFieldsWithoutExposeAnnotation()方法显式启用@Expose注解
    public static void main(String[] args) {
        Gson gson = new GsonBuilder()
                .excludeFieldsWithoutExposeAnnotation()
                .create();

        User user = new User("Jack", 23);
        gson.toJson(user, System.out);
    }

    @ToString
    @AllArgsConstructor
    static
    class User {
        @Expose
        private String username;

        private Integer age;
    }
{"username":"Jack"}

jackson的使用

概述

Jackson有三个核包,分别是 Streaming、Databid、Annotations,通过这些包可以方便的对 JSON 进行操作。

Streaming (opens new window)在 jackson-core 模块。 定义了一些流处理相关的 API 以及特定的 JSON 实现。

Annotations (opens new window)在 jackson-annotations 模块,包含了 Jackson 中的注解。

Databind (opens new window)在 jackson-databind 模块, 在 Streaming 包的基础上实现了数据绑定,依赖于 Streaming 和 Annotations 包。

添加依赖

jackson-databind依赖 jackson-core 和 jackson-annotations,所以可以只显示地添加jackson-databind依赖

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.11.4</version>
</dependency>

ObjectMapper对象映射器

ObjectMapper是Jackson 库中最常用的一个类,使用它可以进行 Java 对象和JSON字符串之间快速转换

readValue() 方法:进行JSON 的反序列化操作,比如可以将字符串、文件流、字节流、字节数组等将常见的内容转换成 Java 对象。

writeValue() 方法:进行JSON 的序列化操作,可以将 Java 对象转换成 JSON 字符串。

ObjectMapper的工作原理是通过 Java Bean 对象的 Get/Set 方法进行转换时映射的,所以Java对象的 Get/Set方法尤为重要。

对象转JSON

    public static void main(String[] args) throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        User user = new User("Jack", 20);
        String json = objectMapper.writeValueAsString(user);
        System.out.println(json);
    }
{"username":"Jack","age":20}

JSON转对象

@Data
class User {
    private String username;
    private Integer age;

    public User() {
    }

    public User(String username, Integer age) {
        this.username = username;
        this.age = age;
    }
}
    public static void main(String[] args) throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        String json = "{\"username\":\"Jack\", \"age\": \"20\"}";

        User user = objectMapper.readValue(json, User.class);
        System.out.println("user = " + user);
    }
user = User(username=Jack, age=20)

JSON转List

    public static void main(String[] args) throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        String json = "[{\"username\":\"Jack\", \"age\": \"20\"},{\"username\":\"Tom\", \"age\": \"22\"}]";
        List<User> userList = objectMapper.readValue(json, new TypeReference<List<User>>() {});
        userList.forEach(System.out::print);
    }
User(username=Jack, age=20)User(username=Tom, age=22)

JSON转Map

JSON转Map适用于在没有一个明确的Java对象时十分实用

    public static void main(String[] args) throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        String json = "{\"username\":\"Jack\", \"age\": \"20\"}";
        Map<String, Object> userNmp = objectMapper.readValue(json, new TypeReference<Map>() {});
        for (Map.Entry<String, Object> entry : userNmp.entrySet()) {
            System.out.println(entry.getKey() + ":" + entry.getValue());
        }
    }

字段忽略

如果在进行JSON 转 Java对象时,JSON中出现 Java 类中不存在的属性,那么在转换时会遇到com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException异常。

使用objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)配置可以忽略不存在的属性。

   public static void main(String[] args) throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        String json = "{\"username\":\"Jack\", \"age\": \"20\",, \"test\": \"test\"}";
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        User user = objectMapper.readValue(json, User.class);
        System.out.println("user = " + user);
    }

日期格式化

开发中通常使用java.util.Date类或时间类java.time.LocalDateTime类(JDK8),两者在Jackson中的处理略有不同。

Date类型

@AllArgsConstructor
@NoArgsConstructor
@Data
class User {
    private String username;
    private Integer age;
    private Date createTime;
}
    public static void main(String[] args) throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        User user = new User("Jack", 20, new Date());
        String json = objectMapper.writeValueAsString(user);
        System.out.println(json);

        User u = objectMapper.readValue(json, User.class);
        System.out.println(u.toString());
    }

未使用@JsonFormat注解,可以正常的进行JSON的序列化与反序列化,但是JSON 中的时间是一个时间戳格式

{"username":"Jack","age":20,"createTime":1669690748654}
User(username=Jack, age=20, createTime=Tue Nov 29 10:59:08 CST 2022)

使用 @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")

{"username":"Jack","age":20,"createTime":"2022-11-29 10:56:28"}
User(username=Jack, age=20, createTime=Tue Nov 29 10:56:28 CST 2022)

LocalDateTime类型

注意:默认情况下进行 LocalDateTime 类的 JSON 转换会遇到报错。异常信息:com.fasterxml.jackson.databind.exc.InvalidDefinitionException

需要添加相应的数据绑定支持包。

 <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-jsr310</artifactId>
            <version>2.13.3</version>
        </dependency>

定义 ObjectMapper 时通过 findAndRegisterModules() 方法来注册依赖。

    public static void main(String[] args) throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper().findAndRegisterModules();
        User user = new User("Jack", 20, LocalDateTime.now());
        String json = objectMapper.writeValueAsString(user);
        System.out.println(json);

        User u = objectMapper.readValue(json, User.class);
        System.out.println(u.toString());
    }
{"username":"Jack","age":20,"createTime":"2022-11-29 11:02:32"}
User(username=Jack, age=20, createTime=2022-11-29T11:02:32)

Jackson常用注解

@JsonIgnore:使用@JsonIgnore 可以忽略某个 Java 对象中的属性,它将不参与 JSON 的序列化与反序列化。

  @JsonIgnore
    private String username;

@JsonGetter:使用 @JsonGetter 可以在对 Java 对象进行 JSON 序列化时自定义属性名称。

	private String username;
	
    @JsonGetter(value = "myName")
    public String getUsername() {
        return username;
    }
    public static void main(String[] args) throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        User user = new User("Jack", 20);
        String json = objectMapper.writeValueAsString(user);
        System.out.println(json);

        User u = objectMapper.readValue(json, User.class);
        System.out.println(u.toString());
    }
{"age":20,"myName":"Jack"}
User(username=Jack, age=20)

@JsonSetter:使用 @JsonSetter 可以在对 JSON 进行反序列化时设置 JSON 中的 key 与 Java 属性的映射关系。

   @JsonSetter(value = "myName")
    private String username;
    public static void main(String[] args) throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        String json="{\"age\":20,\"myName\":\"Jack\"}";
        User u = objectMapper.readValue(json, User.class);
        System.out.println(u.toString());
    }
User(username=Jack, age=20)

你可能感兴趣的:(JAVA,json,java,gson,jackson,fastjson)