json的入门

2021/05/01 Json 共 3734 字,约 11 分钟
闷骚的程序员

1. 初探json

1.1 什么是json?

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。
JSON 使用 Javascript语法来描述数据对象,但是 JSON 仍然独立于语言和平台。
JSON 解析器和 JSON 库支持许多不同的编程语言。 目前非常多的动态(PHP,JSP,.NET,java等)编程语言都支持JSON。

1.2 json有什么用?

  1. 使用基于JavaScript的应用程序,其中包括浏览器扩展和网站。
  2. 使用JSON格式序列化和结构化的数据传输网络连接。
  3. 主要用于服务器和Web应用程序之间的数据传输;比较常见的是作为 RESTful API 返回的格式。
  4. Web服务和API采用JSON格式提供公共数据。

1.3 json有哪些特点?

  1. 易于读写JSON(JSON 具有自我描述性,更易理解)。
  2. 轻量级的基于文本的交换格式。
  3. 独立于语言,json只是一种数据交换格式。

1.4 json和xml的异同?

json与xml相同之处:

  1. json和xml都是纯文本。
  2. json和xml都具有”自我描述性”(人类可读)。
  3. json和xml都具有层级结构(值中存在值)。
  4. json和xml都可通过 JavaScript 进行解析。
  5. json和xml都可使用 AJAX 进行传输。

json与xml不同之处:

  1. json相比xml,没有结束标签。
  2. json比xml更短,更轻量级。
  3. json比xml的读写速度更快。
  4. json能够使用内建的 JavaScript eval() 方法进行解析。
  5. json能够直接使用数组。
  6. json不使用任何保留字。

1.5 json的序列化和反序列化?

json序列化:将json格式的数据结构或者对象转换成json串的过程。
json反序列化:将json字符串转换成json数据结构或者对象的过程。

2. json基础知识点

2.1 json的两种表示结构

  1. 名称/值:这种结构的键值对,构成的一个json字符串,通常表示为json对象。
  2. 值的有序列表:通常表示为json数组。
    这些都是常见的数据结构;事实上大部分现代计算机语言都以某种形式支持它们。这使得一种数据格式在同样基于这些结构的编程语言之间交换成为可能。

2.2 json字符串的语法

  1. 数据表示在键值对中。
  2. 数据之间由逗号分隔。
  3. 大括号表示对象。
  4. 中括号表示数组。

2.3 json文件

  1. 用于保存json文本的文件称为json文件。
  2. 文件扩展名为 .json。
  3. json文本的MIME类型为”application/json”。

3. json可描述的数据类型

3.1 json可以表示的数据

JSON数据表示为键值对的形式,书写格式是:名称/值。其中“名称”需要用双引号括起来,然后紧跟一个“冒号(英文)”,然后就是“值”。
JSON 值可以是:

  1. 数字(整数或浮点数)。
  2. 字符串(在双引号中)。
  3. 逻辑值(true 或 false)。
  4. 数组(在中括号中)。
  5. 对象(在大/花括号中)。
  6. null值。

##3.2 json各种类型值案例 1.JSON 数字可以是整型或者浮点型:

{ "age":30 }

2.JSON 对象在大括号({})中书写,而JSON对象是一个无序设置的名称/值对,对象可以包含多个数据对,数据与数据之间以逗号分隔(包括数组):

{ "name":"菜鸟教程" , "url":"www.runoob.com" }

3.数组在中括号中书写,数组可包含多个对象:

{
  "sites": [
    { "name":"菜鸟教程" , "url":"www.runoob.com" },
    { "name":"google" , "url":"www.google.com" },
    { "name":"微博" , "url":"www.weibo.com" }
  ]
}

注意,数组索引是从零开始的。

4.JSON 布尔值可以是 true 或者 false:

{ "flag":true }

5.JSON 可以设置 null 值:

{ "runoob":null }  

4. JSON与JavaScript的关系如何?

JSON 是 JavaScript 原生格式,这意味着在 JavaScript 中处理 JSON 数据不需要任何特殊的 API 或工具包。

# 5. JSON和Java的关系如何? Java对json的支持,既然json是一种轻量级的数据交换格式,那么各种开发语言都提供了对json的支持。
其中,java的开源json包很多,都对json提供了完美的支持。
一些比较优秀的java json开源包大概有:
alibaba的fastJson。
sun的org.json。
Google的Gson。
Jackson。
等等。

6. Jackson在springmvc中进行入参反序列化,是否严格匹配json字符串中的字段必须和实体中的属性个球,名称等完全一致?

在Spring MVC中使用Jackson进行入参反序列化时,JSON字符串中的字段不需要与实体类中的属性完全匹配。

  1. 属性名称不完全一致:如果JSON中的字段名称与Java实体类的属性名称不完全一致,Jackson可以通过注解(如@JsonProperty)来映射不同的字段名称。例如:

    public class User {
        @JsonProperty("user_name")
        private String username;
    }
    

    通过这种方式,即使JSON中的字段为user_name,Jackson也可以将其正确映射到实体类的username字段。

  2. 忽略多余字段:如果JSON中包含多余的字段,而这些字段在Java实体类中不存在,Jackson默认会忽略这些字段,而不会抛出错误。

  3. 缺少字段处理:如果JSON中缺少实体类中的某些字段,Jackson不会抛出异常,默认会将实体类的这些字段设置为null(对于对象类型)或使用其默认值(如int类型的默认值为0)。

  4. 严格匹配模式:如果你需要Jackson严格匹配JSON字段与实体类字段,可以使用@JsonIgnoreProperties(ignoreUnknown = false)注解来禁止Jackson忽略未知字段:

    @JsonIgnoreProperties(ignoreUnknown = false)
    public class User {
        private String username;
    }
    

    这样,当JSON中包含未知字段时,会抛出UnrecognizedPropertyException

因此,默认情况下,Jackson在Spring MVC中的反序列化是比较宽松的,不需要JSON字段与实体类字段完全一致。

7. 使用JSONObject.parseObject将一个json字符串反序列化一个java对象时,如果这个java对象中新增了一个List属性,而原来的json字符串中没有做任何改变,请问此时能够正常反序列化成功么?

使用 JSONObject.parseObject 方法将 JSON 字符串反序列化为一个 Java 对象时,如果 Java 对象中新增了一个 List<Pojo> 属性,而原来的 JSON 字符串没有这个字段,反序列化是可以正常成功的。

这是因为反序列化过程中的一些默认行为:

  1. 缺少字段不会导致异常:在反序列化过程中,JSON 字符串中缺少某些字段是允许的,FastJSON(JSONObject.parseObject 依赖的库)会根据 JSON 中存在的字段填充相应的 Java 对象属性。对于不存在的字段(如新增的 List<Pojo> 属性),FastJSON 会使用默认值,即 null,而不会抛出异常。

  2. 新增属性处理:如果 Java 对象中增加了新的字段,而 JSON 中没有提供对应的数据,FastJSON 只会忽略这个字段,不会影响其他字段的正常赋值。因此,在这种情况下,新增的 List<Pojo> 属性会被赋值为 null,程序会正常工作。

  3. 向后兼容:这种行为也称为向后兼容,即 JSON 格式的变化与 Java 类的变化之间,某些字段的缺失并不会影响反序列化的成功。这使得在 JSON 数据结构不变的情况下,可以安全地为 Java 类增加新的字段。

举个例子:

假设你的 Java 对象原本是这样的:

public class Person {
    private String name;
    private int age;
}

JSON 字符串为:

{
  "name": "John",
  "age": 30
}

后来你为 Person 类新增了一个 List<Pojo> 属性:

public class Person {
    private String name;
    private int age;
    private List<Pojo> hobbies;  // 新增的属性
}

原来的 JSON 字符串中没有 hobbies 字段,这时候通过 JSONObject.parseObject 反序列化时依然会成功:

Person person = JSONObject.parseObject(jsonString, Person.class);

此时,person.getHobbies() 将返回 null,而 nameage 会正常反序列化。

总结

在使用 JSONObject.parseObject 进行反序列化时,如果 Java 对象中新增了字段,而 JSON 字符串没有更新,反序列化依然会成功,新增的属性会被设置为 null 或其默认值,不会影响其他字段的反序列化。

文档信息

Search

    Table of Contents