SpringMVC-14-JSON数据交互

在人生的道路上,不管是潇洒走一回,或者是千山独行,皆须是自己想走的路,虽然,有的人并不是很快就能找到自己的方向和道路,不过,只要坚持到底,我相信,就一定可以找到自己的路,只要找到路,就不必怕路途遥远了。

导读:本篇文章讲解 SpringMVC-14-JSON数据交互,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

7.Spring MVC JSON数据交互

  • 前后端分离时,后端提供接口,前端进行数据渲染,那么中间需要如何传递数据呢?
  • Spring MVC 在数据绑定的过程中需要对传递数据的格式和类型进行转换,它既可以转换 String 等类型的数据,也可以转换 JSON 等其他类型的数据

7.1 JSON 概述

  • JSON(JavaScript Object Notation, JS 对象标记)是一种轻量级的数据交换格式。与 XML 一样,JSON 也是基于纯文本的数据格式。JSON是一个序列化的对象数组
  • JS任何支持的类型都可以通过 JSON 来表示,例如字符串、数字、对象、数组等。但是对象和数组是比较特殊且常用的两种类型

对象在 JS 中是使用花括号包裹 {} 起来的内容,数据结构为 {key1:value1, key2:value2, …} 的键值对结构

对象在json中以{开始、以}结束,中间部分、多个以英文,分隔的 key/value 对构成,key 和 value 之间以英文:分隔。对象结构的语法结构如下:

JSON键值对是用来保存JS对象的一种方式,和js对象写法类似

{
    key1:value1,
    key2:value2,
}
用例:
{``"firstName"``: ``"Brett"``, ``"lastName"``: ``"McLaughlin"``}

其中,key 必须为 String 类型,可以是对象数组数字字符串或者三个字面量(false、null、true)中的一个。值中的字面值中的英文必须使用小写。

数组在 JS 中是方括号 [] 包裹起来的内容,数据结构为 [“java”, “javascript”, “vb”, …] 的索引结构。在 JS 中,数组是一种比较特殊的数据类型,它也可以像对象那样使用键值对,但还是索引使用得多。同样,值的类型可以是任意类型。

  • 表示数组:和普通的 JS 数组一样,JSON 表示数组的方式也是使用方括号 []。如何用括号将记录组合成一个值?
{ ``"people":[ ``{``"firstName": "Brett",      ``"lastName":"McLaughlin"    ``},   ``{    ``"firstName":"Jason",``"lastName":"Hunter"``}``]``}

在这个示例中,只有一个名为 people的变量,值是包含两个条目的数组,每个条目是一个人的记录,其中包含名和姓

  • 一些合法的JSON数组实例:
{``"a"``: 1, ``"b"``: [1, 2, 3]}
[1, 2, ``"3"``, {``"a"``: 4}]
3.14
"plain_text"
  • 上述两种(对象、数组)数据结构也可以分别组合构成更加复杂的数据结构
{
    "id":"202207030808",
    "name":"张三",
    "hobby":["音乐","足球"],
    "address":{
        "country":"china",
        "zip-code":"10000"
    }
}

7.2 JSON 与 JS 对象的关系

  • JSON (括号最外层带引号)是 JS 对象(括号最外层不带引号)的字符串表示法,它使用文本表示一个 JS 对象的信息,本质是一个字符串
var` `obj = {a: ``'Hello'``, b: ``'World'``}; ``//这是一个对象,注意键名也是可以使用引号包裹的
var` `json = ``'{"a": "Hello", "b": "World"}'``; ``//这是一个 JSON 字符串,本质是一个字符串

7.3 JSON 和 JS 对象互转

  • 要实现从JSON字符串转换为JS对象,使用 JSON.parse() 方法:
var` `obj = JSON.parse(``'{"a": "Hello", "b": "World"}'``); ``//结果是 {a: 'Hello', b: 'World'}
  • 要实现从JS对象转换为JSON字符串,使用 JSON.stringify() 方法:
var` `json = JSON.stringify({a: ``'Hello'``, b: ``'World'``}); ``//结果是 '{"a": "Hello", "b": "World"}'

注意:

7.4 JSON 数据转换

  • 实现浏览器与控制器类之间的 JSON 数据交互,Spring MVC 提供了 MappingJackson2HttpMessageConverter 实现类默认处理 JSON 格式请求响应。该实现类利用 Jackson 开源包读写 JSON 数据,将 Java 对象转换为 JSON 对象和 XML 文档,同时也可以将 JSON 对象和 XML 文档转换为 Java 对象。

  • 给前端json格式的字符串,需要在方法上面加一个@ResponseBody注解,这样返回的字符串不会经过视图解析器,然后引入jackson依赖,spring会自动帮你把返回值转化为json格式,或者直接添加@restcontroller注解

  • 使用注解开发时需要用到两个重要的 JSON 格式转换注解

  • @RequestBody:用于将请求体中的数据绑定到方法的形参中,该注解应用在方法的形参上。 响应体的意思就是服务器要响应的内容,代表这不是一个视图,所以不会走视图解析器
  • @ResponseBody:用于直接返回 return 对象或字符串,该注解应用在方法上。阻止视图解析器解析。配合@Controller使用

@ResponseBody作用是将标注该注解的处理方法的返回结果直接写入 HTTP Response Body**(Response 对象的 body 数据区)中。一般情况下,@ResponseBody 都会在异步获取数据时使用**,被其标注的处理方法返回的数据都将输出到响应流中,客户端获取并显示数据。

  • 早期 JSON 的组装和解析都是通过手动编写代码来实现的。这种方式容易出错
  • 后面有许多的关于组装和解析 JSON 格式信息的工具类出现,如 json-lib、Jackson、Gson 和 FastJson 等,可以解决 JSON 交互的开发效率。
  • jackson是springboot自带解析器
  • json-lib 最早也是应用广泛的 JSON 解析工具,缺点是依赖很多的第三方包,如 commons-beanutils.jar、commons-collections-3.2.jar、commons-lang-2.6.jar、commons-logging-1.1.1.jar、ezmorph-1.0.6.jar 等。对于复杂类型的转换,json-lib 在将 JSON 转换成 Bean 时还有缺陷,比如一个类里包含另一个类的 List 或者 Map 集合,json-lib 从 JSON 到 Bean 的转换就会出现问题。 json-lib 在功能和性能上面都不能满足现在互联网化的需求
  • 开源的 Jackson 是 Spring MVC 内置的 JSON 转换工具。相比 json-lib 框架,Jackson 所依赖 jar 文件较少,简单易用并且性能也要相对高些。并且 Jackson 社区相对比较活跃,更新速度也比较快。但是 Jackson同样会出现上面这种方式的问题,转换的 JSON 格式不是标准的 JSON 格式。
  • **Google的Gson:**是目前功能最全的 JSON 解析工具类,Gson 主要提供了 toJson 与 fromJson 两个转换函数,不需要依赖其它的 jar 文件,就能直接在 JDK 上运行。在使用这两个函数转换之前,需要先创建好对象的类型以及其成员才能成功的将 JSON 字符串转换为相对应的对象。类里面只要有 get 和 set 方法,Gson 完全可以将复杂类型的 JSON 到 Bean 或 Bean 到 JSON 的转换,是 JSON 解析的神器。Gson 在功能上面无可挑剔,但性能比 FastJson 有所差距。
  • 阿里巴巴的FastJson:是用 Java 语言编写的高性能 JSON 处理器。不需要依赖其它的 jar 文件,就能直接在 JDK 上运行。同样FastJson 在复杂类型的 Bean 转换 JSON 上会出现一些问题,可能会出现引用的类型,导致 JSON 转换出错,需要制定引用。FastJson 采用独创的算法,将 parse 的速度提升到极致,超过所有 JSON 库。FastJson2已经出来了,原作者重新写了,与原来的底层都变了,速度提升134%
  • 实际开发时可以将Gson和FastJson混合使用,如果只是功能要求,没有性能要求,可以使用 Gson。如果有性能上面的要求可以使用 Gson 将 Bean 转换 JSON 确保数据的正确,使用 FastJson 将 JSON 转换 Bean。

  • 工具类的使用

  • 导入依赖

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.3</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>2.0.5</version>
</dependency>
<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.9.0</version>
</dependency>
  • 实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    String username;
    int age;
    LocalDate birthday;  //jackson对复杂对象支持不够
}
  • 控制器类测试,单个实体类转换后是json字符串(对象形式),一个集合或数组转换后是数组格式的json字符串
@Controller
@RequestMapping("/user")
public class UserController {

    @RequestMapping(value = "/gj01",produces = "application/json;charset=utf-8")
    @ResponseBody
    public String getjson01() throws JsonProcessingException {
        //com.fasterxml.jackson.databind.ObjectMapper;
        ObjectMapper objectMapper = new ObjectMapper();
        User user = new User("张三", 18, LocalDate.now());
        return objectMapper.writeValueAsString(user);
        //`java.time.LocalDate` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling
        
        //将LocalDate.now()换成new java.util.Date()
        {"username":"张三","age":18,"birthday":1656857490891}   //转换为时间戳
    }
    
    
    @RequestMapping(value = "/gj02",produces = "application/json;charset=utf-8")
    @ResponseBody
    public String getjson02() throws JsonProcessingException {
        User user = new User("张三", 18, LocalDate.now());
        return JSON.toJSONString(user);  //com.alibaba.fastjson2.JSON;
        //{"age":18,"birthday":"2022-07-03","username":"张三"}
    }

    @RequestMapping(value = "/gj03",produces = "application/json;charset=UTF-8")
    @ResponseBody
    public String getjson03() throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        User user = new User("张三", 18, LocalDate.now());
        Gson gson = new Gson();
        gson.toJson(user);
        return gson.toJson(user);
        //{"username":"张三","age":18,"birthday":{"year":2022,"month":7,"day":3}}
    }
}

7.5 jackson对日期类的转换

  • jackson日期类型直接转为json,显示的是时间戳

  • 所以需要jackson对日期类型转换格式进行设置

  • 方式1:传统方式SimpleDateFormat

@RequestMapping(value = "/gj04")
@ResponseBody
public String getjson04() throws JsonProcessingException {
    ObjectMapper objectMapper = new ObjectMapper();
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    return objectMapper.writeValueAsString(sdf.format(new Date()));
}
  • 方式2:jackson设置
@RequestMapping(value = "/gj05")
@ResponseBody
public String getjson05() throws JsonProcessingException {
    ObjectMapper objectMapper = new ObjectMapper();
    /*关闭使用时间戳的方式*/
    objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    //指定日期格式
    objectMapper.setDateFormat(sdf);
    return objectMapper.writeValueAsString(new Date());
}

7.6 fastjson使用

  • JSONObject代表json对象,实现了map接口,通过各种形式的get()方法获取json对象中的数据,也可利用size(),isEmpty()方法获取”键值对“个数和判断是否空。本质是实现map结果并调佣接口方法完成的。对应js对象

  • JSONArray代表json对象数组,内部是List接口的方法完成操作

  • JSON代表JSONObject和JSONArray的转换

  • 分析源码,JSON的这些方法主要是实现json对象,json对象数组,json字符串,javabean对象的相互转换

  • 主要方法

public static String toJSONString(Object object) //java对象转JSON字符串
public static <T> T parseObject(String text, Class<T> clazz) //JSON字符串转java对象
public static Object toJSON(Object javaObject) //java对象转json对象,返回Object再强转JSONObject
public static <T> T toJavaObject(JSON json, Class<T> clazz)//json对象转java对象
  • fastjson的运行速度快比jacjson快一倍
  • 如果返回JSON字符串太长会导致截断的问题

下一篇:SpringMVC-15-乱码问题处理

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/123888.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!