Json格式数据解析

简介: Json格式数据解析

一、简介

XML这种数据格式。XML的特点是功能全面,但标签繁琐,格式复杂。在Web上使用XML现在越来越少,取而代之的是JSON这种数据结构。

JSON是JavaScript Object Notation的缩写,它去除了所有JavaScript执行代码,只保留JavaScript的对象格式。典型的JSON如下:

  1. json对象
{
    "ID": 1001,
    "name": "张三",
}
/*
特点:
数据在花括号中数据以"键:值"对的形式出现(其中键多以字符串形式出现,值可取字符串,数值,甚至其他json对象)
每两个"键:值"对以逗号分隔(最后一个"键:值"对省略逗号)
*/
  1. json对象数组
{
    "部门名称":"研发部",
    "部门成员":[
    {"ID": 1001, "name": "张三", "age": 24},
    {"ID": 1002, "name": "李四", "age": 25},
    {"ID": 1003, "name": "王五", "age": 22}],
    "部门位置":"xx楼21号"
}
  1. json字符串JSON字符串也是在平时开发中使用较多的,json字符串应满足以下条件:
    1:它必须是一个字符串,由" "或者' '包裹数据,支持字符串的各种操作
    2:里面的数据格式应该要满足其中一个格式,可以是json对象,也可以是json对象数组或者是两种基本形式的组合变形。

二、特点

JSON作为数据传输的格式,有几个显著的优点:

  • JSON只允许使用UTF-8编码,不存在编码问题;
  • JSON只允许使用双引号作为key,特殊字符用\转义,格式简单;
  • 浏览器内置JSON支持,如果把数据用JSON发送给浏览器,可以用JavaScript直接处理。

三、前端处理json数据

开发Web应用的时候,使用JSON作为数据传输,在浏览器端非常方便。因为JSON天生适合JavaScript处理,所以,绝大多数REST API都选择JSON作为数据传输格式

1.json字符串转成对象, 使用json.parse(jsonStr)

2.json格式对象转成json格式字符串,使用JSON.stringify(jsonObj);

var jsonObj = {"name":"张三","age":14};

使用JSON.stringify(jsonObj);

四、Java如何对JSON进行读写?

在Java中,针对JSON也有标准的JSR 353 API,但是我们在前面讲XML的时候发现,如果能直接在XML和JavaBean之间互相转换是最好的。类似的,如果能直接在JSON和JavaBean之间转换,那么用起来就简单多了。

常用的用于解析JSON的第三方库有:

  • Jackson
  • Gson
  • Fastjson

1、使用FastJson解析数据

1.1、语法

三者之间的关系如下,JSONObject和JSONArray继承JSON

JSONObject代表json对象,

JSONArray代表json对象数组,

JSON代表JSONObject和JSONArray的转化。

JSONObject类使用

JSONObject实现了Map接口,而json对象中的数据都是以"键:值"对形式出现, JSONObject底层操作是由Map实现的。类中主要是get()方法。JSONObject相当于json对象,该类中主要封装了各种get方法,通过"键:值"对中的键来获取其对应的值。

JSONArray类使用

JSONArray的内部是通过List接口中的方法来完成操作的。JSONArray代表json对象数组,json数组对象中存储的是一个个json对象,所以类中的方法主要用于直接操作json对象。比如其中的add(),remove(),containsAll()方法,对应于json对象的添加,删除与判断。 其内部主要由List接口中的对应方法来实现。

跟JSONObject一样,JSONArray里面也有一些get()方法,不过不常用,最有用的应该是getJSONObject(int index)方法,该方法用于获取json对象数组中指定位置的JSONObject对象,配合size()方法,可用于遍历json对象数组中的各个对象。 通过以上两个方法,在配合for循环,即可实现json对象数组的遍历。此外JSONArray中也实现了迭代器方法来遍历。 通过遍历得到JSONObject对象,然后再利用JSONObject类中的get()方法,即可实现最终json数据的获取。

JSON类使用

JSON类主要是实现转化用的,最后的数据获取,还是要通过JSONObject和JSONArray来实现。类中的主要是实现json对象,json对象数组,javabean对象,json字符串之间的相互转化。

1.2、使用

json字符串—》JSONObject

用JSON.parseObject()方法即可将JSon字符串转化为JSON对象,利用JSONObject中的get()方法来获取JSONObject中的相对应的键对应的值

//json格式数据---对象类型
String  JSON_OBJ_STR = "{\"studentName\":\"lily\",\"studentAge\":12}";
JSONObject jsonObject = JSON.parseObject(JSON_OBJ_STR);
System.out.println("StudentName: " + jsonObject.getString("studentName") + "," + "StudentAge: " + jsonObject.getInteger("studentAge"));

JSONObject—》json字符串

用JSON.toJSONString()方法即可将JSON对象转化为JSON字符串

JSON字符串数组—》JSONArray

将JSON字符串数组转化为JSONArray,通过JSON的parseArray()方法。JSONArray本质上还是一个数组,对其进行遍历取得其中的JSONObject,然后再利用JSONObject的get()方法取得其中的值。有两种方式进行遍历

方式一:通过jsonArray.size()获取JSONArray中元素的个数,再通过getJSONObject(index)获取相应位置的JSONObject,循环变量取得JSONArray中的JSONObject,再利用JSONObject的get()进行取值。

方式二:通过jsonArray.iterator()获取迭代器

JSON_ARRAY_STR = "     [{\"studentName\":\"lily\",\"studentAge\":12}," +
            "{\"studentName\":\"lucy\",\"studentAge\":15}]";
JSONArray jsonArray = JSON.parseArray(JSON_ARRAY_STR);
// 遍历方式一
//        int size = jsonArray.size();
//        for(int i = 0;i < size;i++){
//            JSONObject jsonObject = jsonArray.getJSONObject(i);
//            System.out.println("studentName: " + jsonObject.getString("studentName") + ",StudentAge: " + jsonObject.getInteger("studentAge"));
//        }
// 遍历方式二
        Iterator<Object> iterator = jsonArray.iterator();
        while (iterator.hasNext()){
            JSONObject jsonObject = (JSONObject) iterator.next();
            System.out.println("studentName: " + jsonObject.getString("studentName") + ",StudentAge: " + jsonObject.getInteger("studentAge"));
        }

JSONArray—》json字符串

用JSON.toJSONString()方法即可将JSONArray转化为JSON字符串

json字符串—》JavaBean

String  JSON_OBJ_STR = "{\"studentName\":\"lily\",\"studentAge\":12}";
// 第一种方式
        JSONObject jsonObject = JSON.parseObject(JSON_OBJ_STR);
        String studentName = jsonObject.getString("studentName");
        Integer studentAge = jsonObject.getInteger("studentAge");
        Student student = new Student(studentName, studentAge);
// 第二种方式,//第二种方式,使用TypeReference<T>类,由于其构造方法使用protected进行修饰,故创建其子类
        Student student1 = JSON.parseObject(JSON_OBJ_STR, new TypeReference<Student>() {});
// 第三种方式,通过反射,建议这种方式
        Student student2 = JSON.parseObject(JSON_OBJ_STR, Student.class);

JavaBean —》json字符串

也是通过JSON的toJSONString,不管是JSONObject、JSONArray还是JavaBean转为为JSON字符串都是通过JSON的toJSONString方法。

Student lily = new Student("lily", 12);
String s = JSON.toJSONString(lily);

json字符串数组—》JavaBean-List

JSON_ARRAY_STR = "     [{\"studentName\":\"lily\",\"studentAge\":12}," +
            "{\"studentName\":\"lucy\",\"studentAge\":15}]";
// 方式一:
        JSONArray jsonArray = JSON.parseArray(JSON_ARRAY_STR);
        //遍历JSONArray
        List<Student> students = new ArrayList<Student>();
        Iterator<Object> iterator = jsonArray.iterator();
        while (iterator.hasNext()){
            JSONObject next = (JSONObject) iterator.next();
            String studentName = next.getString("studentName");
            Integer studentAge = next.getInteger("studentAge");
            Student student = new Student(studentName, studentAge);
            students.add(student);
        }
        // 方式二,使用TypeReference<T>类,由于其构造方法使用protected进行修饰,故创建其子类
        List<Student> studentList = JSON.parseObject(JSON_ARRAY_STR,new TypeReference<ArrayList<Student>>() {});
        // 方式三,使用反射
        List<Student> students1 = JSON.parseArray(JSON_ARRAY_STR, Student.class);
        System.out.println(students1);

JavaBean-List —》json字符串数组

JavaBean_List到json字符串-数组类型的转换,直接调用JSON.toJSONString()方法即可

复杂嵌套json格式字符串—》JavaBean_obj

对于复杂嵌套的JSON格式,利用JavaBean进行转换的时候要注意:

有几个JSONObject就定义几个JavaBean

内层的JSONObject对应的JavaBean作为外层JSONObject对应的JavaBean的一个属性

public class Student {
    private String studentName;
    private int studentAge;
    public Student() {
    }
    public Student(String studentName, int studentAge) {
        this.studentName = studentName;
        this.studentAge = studentAge;
    }
    public String getStudentName() {
        return studentName;
    }
    public void setStudentName(String studentName) {
        this.studentName = studentName;
    }
    public int getStudentAge() {
        return studentAge;
    }
    public void setStudentAge(int studentAge) {
        this.studentAge = studentAge;
    }
    @Override
    public String toString() {
        return "Student{" +
                "studentName='" + studentName + '\'' +
                ", studentAge=" + studentAge +
                '}';
    }
}
 
 
import java.util.List;
public class Teacher {
    private String teacherName;
    private int teacherAge;
    private Course course;
    private List<Student> students;
    public Teacher() {
    }
    public Teacher(String teacherName, int teacherAge, Course course, List<Student> students) {
        this.teacherName = teacherName;
        this.teacherAge = teacherAge;
        this.course = course;
        this.students = students;
    }
    public String getTeacherName() {
        return teacherName;
    }
    public void setTeacherName(String teacherName) {
        this.teacherName = teacherName;
    }
    public int getTeacherAge() {
        return teacherAge;
    }
    public void setTeacherAge(int teacherAge) {
        this.teacherAge = teacherAge;
    }
    public Course getCourse() {
        return course;
    }
    public void setCourse(Course course) {
        this.course = course;
    }
    public List<Student> getStudents() {
        return students;
    }
    public void setStudents(List<Student> students) {
        this.students = students;
    }
    @Override
    public String toString() {
        return "Teacher{" +
                "teacherName='" + teacherName + '\'' +
                ", teacherAge=" + teacherAge +
                ", course=" + course +
                ", students=" + students +
                '}';
    }
}
 
 
public class Course {
    private String courseName;
    private int code;
    public Course() {
    }
    public Course(String courseName, int code) {
        this.courseName = courseName;
        this.code = code;
    }
    public String getCourseName() {
        return courseName;
    }
    public void setCourseName(String courseName) {
        this.courseName = courseName;
    }
    public int getCode() {
        return code;
    }
    public void setCode(int code) {
        this.code = code;
    }
    @Override
    public String toString() {
        return "Course{" +
                "courseName='" + courseName + '\'' +
                ", code=" + code +
                '}';
    }
}
 
 
//第一种方式,使用TypeReference<T>类,由于其构造方法使用protected进行修饰,故创建其子类
    Teacher teacher = JSON.parseObject(COMPLEX_JSON_STR, new TypeReference<Teacher>() {});
// 第二种方式,使用反射
    Teacher teacher1 = JSON.parseObject(COMPLEX_JSON_STR, Teacher.class);

JavaBean_obj —》复杂json格式字符串

Teacher teacher = JSON.parseObject(COMPLEX_JSON_STR, Teacher.class);
    String s = JSON.toJSONString(teacher);

备注:设置实体中的某个属性转json

2、使用JackJson解析数据

2.1、简介

Jackson 是当前用的比较广泛的,用来序列化和反序列化 json 的 Java 的开源框架。

Jackson 社区相对比较活跃,更新速度也比较快, 从 Github 中的统计来看,Jackson 是最流行的 json 解析器之一 。

Spring MVC 的默认 json 解析器便是 Jackson。

Jackson 优点很多。 Jackson 所依赖的 jar 包较少 ,简单易用。

与其他 Java 的 json 的框架 Gson 等相比, Jackson 解析大的 json 文件速度比较快

Jackson 运行时占用内存比较低,性能比较好

Jackson 有灵活的 API,可以很容易进行扩展和定制。

Jackson 的 1.x 版本的包名是 org.codehaus.jackson ,当升级到 2.x 版本时,包名变为 com.fasterxml.jackson。

Jackson可以解析JSON也可以解析xml

Jackson 的核心模块由三部分组成。

jackson-core,核心包,提供基于"流模式"解析的相关 API,它包括 JsonPaser 和 JsonGenerator。 Jackson 内部实现正是通过高性能的流模式 API 的 JsonGenerator 和 JsonParser 来生成和解析 json。
jackson-annotations,注解包,提供标准注解功能;
jackson-databind ,数据绑定包, 提供基于"对象绑定" 解析的相关 API ( ObjectMapper ) 和"树模型" 解析的相关 API (JsonNode);基于"对象绑定" 解析的 API 和"树模型"解析的 API 依赖基于"流模式"解析的 API。
源码地址:https://github.com/FasterXML/jackson
当然了,jackson-databind 依赖 jackson-core 和 jackson-annotations,所以可以只显示地添加jackson-databind依赖,jackson-core 和 jackson-annotations 也随之添加到 Java 项目工程中。

<dependency>

 <groupId>com.fasterxml.jackson.core</groupId>

 <artifactId>jackson-databind</artifactId>

 <version>2.9.6</version>

</dependency>

2.3、使用

使用下面的代码解析一个JSON文件:

InputStream input = Main.class.getResourceAsStream("/book.json");
ObjectMapper mapper = new ObjectMapper();
// 反序列化时忽略不存在的JavaBean属性:
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Book book = mapper.readValue(input, Book.class);

核心代码是创建一个ObjectMapper对象。关闭DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES功能使得解析时如果JavaBean不存在该属性时解析不会报错。

把JSON解析为JavaBean的过程称为反序列化。如果把JavaBean变为JSON,那就是序列化。要实现JavaBean到JSON的序列化,只需要一行代码:

String json = mapper.writeValueAsString(book);

要把JSON的某些值解析为特定的Java对象,例如LocalDate,也是完全可以的。例如:

{
    "name": "Java核心技术",
    "pubDate": "2016-09-01"
}

要解析为:

public class Book {
    public String name;
    public LocalDate pubDate;
}

只需要引入标准的JSR 310关于JavaTime的数据格式定义至Maven:

  • com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.12.0

然后,在创建ObjectMapper时,注册一个新的JavaTimeModule

ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule());

有些时候,内置的解析规则和扩展的解析规则如果都不满足我们的需求,还可以自定义解析。

举个例子,假设Book类的isbn是一个BigInteger

public class Book {
  public String name;
  public BigInteger isbn;
}

但JSON数据并不是标准的整形格式:

{
    "name": "Java核心技术",
    "isbn": "978-7-111-54742-6"
}

直接解析,肯定报错。这时,我们需要自定义一个IsbnDeserializer,用于解析含有非数字的字符串:

public class IsbnDeserializer extends JsonDeserializer<BigInteger> {
    public BigInteger deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        // 读取原始的JSON字符串内容:
        String s = p.getValueAsString();
        if (s != null) {
            try {
                return new BigInteger(s.replace("-", ""));
            } catch (NumberFormatException e) {
                throw new JsonParseException(p, s, e);
            }
        }
        return null;
    }
}

然后,在Book类中使用注解标注:

public class Book {
    public String name;
    // 表示反序列化isbn时使用自定义的IsbnDeserializer:
    @JsonDeserialize(using = IsbnDeserializer.class)
    public BigInteger isbn;
}

类似的,自定义序列化时我们需要自定义一个IsbnSerializer,然后在Book类中标注@JsonSerialize(using = ...)即可。

反序列化

在反序列化时,Jackson要求Java类需要一个默认的无参数构造方法,否则,无法直接实例化此类。存在带参数构造方法的类,如果要反序列化,注意再提供一个无参数构造方法。

对于enum字段,Jackson按String类型处理,即:

class Book {
    public DayOfWeek start = MONDAY;
}

序列化为:

{
    "start": "MONDAY"
}

对于record类型,Jackson会自动找出它的带参数构造方法,并根据JSON的key进行匹配,可直接反序列化。对record类型的支持需要版本2.12.0以上。

使用详解参考

Jackson使用详解_wh柒八九的博客-CSDN博客_jackson使用


相关文章
|
2月前
|
XML JSON API
淘宝商品详情API的调用流程(python请求示例以及json数据示例返回参考)
JSON数据示例:需要提供一个结构化的示例,展示商品详情可能包含的字段,如商品标题、价格、库存、描述、图片链接、卖家信息等。考虑到稳定性,示例应基于淘宝开放平台的标准响应格式。
|
2月前
|
JSON Java 数据格式
微服务——SpringBoot使用归纳——Spring Boot返回Json数据及数据封装——封装统一返回的数据结构
本文介绍了在Spring Boot中封装统一返回的数据结构的方法。通过定义一个泛型类`JsonResult&lt;T&gt;`,包含数据、状态码和提示信息三个属性,满足不同场景下的JSON返回需求。例如,无数据返回时可设置默认状态码&quot;0&quot;和消息&quot;操作成功!&quot;,有数据返回时也可自定义状态码和消息。同时,文章展示了如何在Controller中使用该结构,通过具体示例(如用户信息、列表和Map)说明其灵活性与便捷性。最后总结了Spring Boot中JSON数据返回的配置与实际项目中的应用技巧。
136 0
|
2月前
|
JSON Java fastjson
微服务——SpringBoot使用归纳——Spring Boot返回Json数据及数据封装——使用 fastJson 处理 null
本文介绍如何使用 fastJson 处理 null 值。与 Jackson 不同,fastJson 需要通过继承 `WebMvcConfigurationSupport` 类并覆盖 `configureMessageConverters` 方法来配置 null 值的处理方式。例如,可将 String 类型的 null 转为 &quot;&quot;,Number 类型的 null 转为 0,避免循环引用等。代码示例展示了具体实现步骤,包括引入相关依赖、设置序列化特性及解决中文乱码问题。
71 0
|
2月前
|
JSON Java fastjson
微服务——SpringBoot使用归纳——Spring Boot返回Json数据及数据封装——Spring Boot 默认对Json的处理
本文介绍了在Spring Boot中返回Json数据的方法及数据封装技巧。通过使用`@RestController`注解,可以轻松实现接口返回Json格式的数据,默认使用的Json解析框架是Jackson。文章详细讲解了如何处理不同数据类型(如类对象、List、Map)的Json转换,并提供了自定义配置以应对null值问题。此外,还对比了Jackson与阿里巴巴FastJson的特点,以及如何在项目中引入和配置FastJson,解决null值转换和中文乱码等问题。
113 0
|
22天前
|
XML JSON API
如何在 Postman 中上传文件和 JSON 数据
如果你想在 Postman 中同时上传文件和 JSON 数据,本文将带你一步一步地了解整个过程,包括最佳实践和技巧,让你的工作更轻松。
|
23天前
|
JSON JavaScript 前端开发
如何在 Postman 中发送 JSON 数据
我们将深入探讨使用 Postman 发送 JSON 数据这一主题,Postman 是一款强大的 API 测试和开发工具。无论您是经验丰富的开发人员还是新手,掌握这项技能对于高效的 API 测试和开发都至关重要。
|
28天前
|
JSON Java 数据库连接
怎样用 esProc 计算来自 Restful 的多层 json 数据
esProc 是一款强大的数据处理工具,可简化 Java 处理 Restful 接口返回的复杂多层 JSON 数据的难题。通过 esProc,不仅能轻松访问和解析 Restful 数据,还能高效完成复杂计算任务,并可无缝嵌入 Java 应用中作为计算引擎使用。例如,筛选特定分类订单或计算金额,esProc 的脚本简洁直观,远优于传统 SQL 或纯 Java 实现。此外,esProc 支持安全认证(如 Cookie 和 Token)及 JDBC 集成,为开发者提供灵活高效的解决方案。
|
1月前
|
JSON JavaScript 数据格式
何如定义 JSON Schema 并验证该 json 数据?
本文定义了一个包含 audio 和 tags 两个必需属性的 JSON Schema,用于规范数据结构。其中,audio 是非空字符串,表示音频组件;tags 是非空数组,表示标签组件。通过示例数据和验证工具(如 ajv, NJsonSchema),可确保 JSON 数据符合 Schema 要求,从而保障数据的一致性和正确性。
94 1
|
2月前
|
存储 JSON API
淘宝商品详情API接口概述与JSON数据示例
淘宝商品详情API是淘宝开放平台提供的核心接口之一,为开发者提供了获取商品深度信息的能力。以下是技术细节和示例:
|
2月前
|
缓存 监控 搜索推荐
【实战解析】smallredbook.item_get_video API:小红书视频数据获取与电商应用指南
本文介绍小红书官方API——`smallredbook.item_get_video`的功能与使用方法。该接口可获取笔记视频详情,包括无水印直链、封面图、时长、文本描述、标签及互动数据等,并支持电商场景分析。调用需提供`key`、`secret`和`num_iid`参数,返回字段涵盖视频链接、标题、标签及用户信息等。同时,文章提供了电商实战技巧,如竞品监控与个性化推荐,并列出合规注意事项及替代方案对比。最后解答了常见问题,如笔记ID获取与视频链接时效性等。

推荐镜像

更多