前后端分离时代:
后端部署后端, 提供接口, 提供数据;
↓
json
↑
前端独立部署, 负责渲染后端的数据;
8.1、什么是JSON
- JSON(JavaScipt Object Notation, JS 对象标记) 是一种轻量级数据交换格式, 目前使用特别广泛。
- 采用完全独立与编程语言的文本格式来存储和表示数据。
- 简洁和清晰的层次结构使得JSON成为理想的数据交换语言。
- 易于人阅读和编写, 同时也易于机器解析和生成, 并有效地提升网络传输效率。
在JavaScript语言中, 一切都是对象。因此, 任何JavaScript支持的类型都可以通过JSON来表示, 例如字符串、对象、数组等。看看他的要求和语法格式:
- JSON对象表示为键值对, 数据由 , 分隔
- {} 保存对象
- [] 保存数组
8.1.1、JSON对象和JSON字符串的区别?
JSON对象是直接可以使用jQuery操作的格式。
JSON字符串仅仅只是一个字符串,一个整体,不截取的话没办法读取其中存储的数据,不能直接使用, 除非alert()它。
JSON对象
有时候在做项目的时候时常将这两个概念弄混淆,尤其是在使用springmvc的时候,后台@RequestBody接受的是一个json格式的字符串,一定是一个字符串。
先介绍一下json对象,首先说到对象的概念,对象的属性是可以用:对象.属性进行调用的。例如:**var _person_**={**"name"**:**"zhangsan"**,**"sex"**:**"男"**,**"age"**:**"24"**}_//json对象<br />alert_(**_person_**.**name**);_//zhangsan<br />alert_(**typeof _person_**);_//object_
person就是json对象。可以用perosn.name这种方式进行属性的调用。第三行代码就是看person的类型,为object类型。
JSON字符串
字符串,我们常说的JavaScript中的字符串是单引号或者双引号引起来的。**var _person_**=**'{"name":"zhangsan","sex":"男","age":"24"}'**;_//json字符串 <br />alert_(**_person_**);_//{"name":"zhangsan","sex":"男","age":"24"} <br />alert_(**typeof _person_**);_//string_
8.1.2、JSON 键值对
用来保存JavaScript对象的一种方式, 和JavaScript对象的写法也大同小异, 键值对组合的键名写在前面用 “” 包裹,使用 : 分隔, 然后紧接着值;
{"name":"身伤易逝"}
{"age":"18"}
{"sex":"男"}
- JSON是JavaScript对象的字符串表示法, 它使用文本表示一个JS对象的信息, 本质是一个字符串。
var obj={a:'ssys', b:'qsnh'};//这是一个对象,注键名也可以使用引号包裹
var json='{"a":"ssys", "b":"sqnh"}';//这是一个JSON字符串,本质是一个字符串
8.1.3、JSON与JavaScript对象相互转换
- JSON字符串 转换到 JavaScript对象, 使用**JSON.parse()**方法:
var obj=JSON.paese('{"a":"ssys", "b":"sqnh"}');
//结果是{a:'ssys', b:'qsnh'}
- JavaScript对象 转换到 JSON字符串, 使用**JSON.stringify()**方法:
var json=JSON.stringify({a:'ssys', b:'qsnh'});
//结果是'{"a":"ssys", "b":"sqnh"}'
练习:
<script type="text/javascript">
'use strict';
//编写一个JavaScript对象 ES6
var user = {
name: "身伤易逝",
age: 18,
sex: "男"
};
console.log(user);
//将js对象转换为json对象
var json = JSON.stringify(user);
console.log(json);//{"name":"身伤易逝","age":18,"sex":"男"}
//将json对象转换为js对象
var js = JSON.parse(json);
console.log(js) //Object
//age: 18
//name: "身伤易逝"
//sex: "男"
</script>
8.2、Controller返回JSON数据(Jackson)
- Jackson是目前比较好的json解析工具
- 工具不止一个, 比如阿里巴巴的fastjson等等。
//对象 → json字符串
String json = mapper.writeValueAsString(对象);
8.2.1、返回一个对象
Jackson使用步骤:
①使用Jackson需要导包
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.0</version>
</dependency>
②编写控制器Controller
方法一:
@Controller
public class UserController {
@RequestMapping("/j1")
@ResponseBody_//他就不会走视图解析器, 会在页面直接返回一个字符串_ _**public **String json1() **throws **JsonProcessingException {
……
**return **json;
}
@Controller
public class UserController {
@RequestMapping("/j1")
@ResponseBody//他就不会走视图解析器, 会在页面直接返回一个字符串,但会乱码
public String json1() throws JsonProcessingException {
//jackson, ObjectMapper
ObjectMapper mapper = new ObjectMapper();
//创建一个对象
User user = new User("身伤易逝", 18, "男");
//对象 → json字符串
String json = mapper.writeValueAsString(user);
return json;
}
}
方法二:
@RestController_//他的所有方法就不会走视图解析器, 会在页面直接返回一个字符串_
public class UserController2 {
@RequestMapping("/j2")__ _**public **String json1() **throws **JsonProcessingException {
……
**return **json;
}
@RestController//他的所有方法就不会走视图解析器, 会在页面直接返回一个字符串
public class UserController2 {
@RequestMapping("/j2")
public String json1() throws JsonProcessingException {
//jackson, ObjectMapper
ObjectMapper mapper = new ObjectMapper();
//创建一个对象
User user = new User("身伤易逝", 18, "男");
//对象 → json字符串
String json = mapper.writeValueAsString(user);
return json;
}
}
页面:
{“name”:“身伤易逝”,“age”:18,“sex”:“男”}
8.2.2、返回数组对象
@RequestMapping(value = "/j2", produces = "application/json;charset=utf-8")
public String json2() throws JsonProcessingException {
//jackson, ObjectMapper
ObjectMapper mapper = new ObjectMapper();
ArrayList<User> list = new ArrayList<>();
User user1 = new User("身伤易逝", 18, "男");
User user2 = new User("情伤难合", 18, "男");
User user3 = new User("身伤易愈", 18, "男");
User user4 = new User("心伤难合", 18, "男");
list.add(user1);
list.add(user2);
list.add(user3);
list.add(user4);
//对象 → json字符串
String json = mapper.writeValueAsString(list);
return json;
}
页面: [{“name”:“身伤易逝”,“age”:18,“sex”:“男”},{“name”:“情伤难合”,“age”:18,“sex”:“男”},{“name”:“身伤易愈”,“age”:18,“sex”:“男”},{“name”:“心伤难合”,“age”:18,“sex”:“男”}]
8.2.3、返回时间对象
1、ObjectMapper,时间解析后的默认格式为: Timestamp, 时间戳
//时间对象
@RequestMapping(value = "/j3", produces = "application/json;charset=utf-8")
public String json3() throws JsonProcessingException {
//jackson, ObjectMapper
ObjectMapper mapper = new ObjectMapper();
Date date = new Date();
//对象 → json字符串
String json = mapper.writeValueAsString(date);
return json;
}
2、自定义时间格式
法一: 变化输出的字符串
//时间对象
@RequestMapping(value = "/j3", produces = "application/json;charset=utf-8")
public String json3() throws JsonProcessingException {
//jackson, ObjectMapper
ObjectMapper mapper = new ObjectMapper();
Date date = new Date();
//自定义日期格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//对象 → json字符串
String json = mapper.writeValueAsString(sdf.format(date));
return json;
}
法二: 取消默认格式(Timestamp, 时间戳)
//时间对象
@RequestMapping(value = "/j3", produces = "application/json;charset=utf-8")
public String json3() throws JsonProcessingException {
//jackson, ObjectMapper
ObjectMapper mapper = new ObjectMapper();
//不使用时间戳格式
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);
//自定义日期格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//指定日期格式
mapper.setDateFormat(sdf);
Date date = new Date();
//对象 → json字符串
String json = mapper.writeValueAsString(sdf.format(date));
return json;
}
页面: "2021-11-03 17:22:49"
8.2.4、JSON工具类
package com.utils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import java.text.SimpleDateFormat;
public class JsonUtils {
//默认用标准格式(如果不传格式)
public static String getJson(Object oject){
return getJson(oject,"yyyy-MM-dd HH:mm:ss");
}
//自定义时间格式
public static String getJson(Object object,String dataFormat) {
ObjectMapper mapper = new ObjectMapper();
//不使用时间戳格式
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);
//自定义日期格式
SimpleDateFormat sdf = new SimpleDateFormat(dataFormat);
//指定日期格式
mapper.setDateFormat(sdf);
try {
return mapper.writeValueAsString(object);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return null;
}
}
使用:
@RequestMapping(value = "/j1", produces = "application/json;charset=utf-8")
public String json1() throws JsonProcessingException {
User user = new User("身伤易逝", 18, "男");
return JsonUtils.getJson(user);
}
8.3、Jackson、@RestController的乱码问题
@RequestMapping(value = **"/j1"**,produces = **"application/json;charset=utf-8"**)
@Controller
public class UserController {
@RequestMapping(value = "/j1",produces = "application/json;charset=utf-8")
@ResponseBody//他就不会走视图解析器, 会在页面直接返回一个字符串
public String json1() throws JsonProcessingException {
//jackson, ObjectMapper
ObjectMapper mapper = new ObjectMapper();
//创建一个对象
User user = new User("身伤易逝", 18, "男");
//对象 → json字符串
String json = mapper.writeValueAsString(user);
return json;
}
}
8.4、代码优化(乱码统一解决)
上一种方法比较麻烦, 如果项目中有许多请求则每一个都要添加, 可以通过Spring配置统一指定
<!--JSON乱码问题解决-->
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="UTF-8"/>
</bean>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
<property name="failOnEmptyBeans" value="false"/>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
8.5、FastJson(比Jackson更简洁)
8.5.1、什么是FastJson
fastJson.jar是阿里开发的一款专门用于Java开发的包, 可以方便的实现json对象与JavaBean对象的转换, 实现JavaBean对象与json字符串的转换, 实现json对象与json字符串的转换。实现转换的方法很多, 最后的实现结果都一样。
使用需要导入依赖
<!--fastjson工具-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.78</version>
</dependency>
8.5.2、主要的类
-
JSONObject 代表 json对象
- JSONObject实现了Map接口, 猜想JSONObject底层操作是由Map实现的
- JSONObject对应json对象, 通过各种形式的get()方法可以获取json对象的数据, 也可以利用诸如size()、**isEmpty()**等方法获取 "键: 值"对的个数和判断是否为空。其本质是通过实现Map接口并调用接口中的方法完成的。
-
JSONArray 代表json对象数组
- 内部是有List接口中的方法来操作完成的。
- JSON 代表JSONObject和JSONArray的转化
- JSON类源码分析和使用
- 仔细观察这些方法, 主要是实现json对象、json对象数组、javabean对象、json字符串之间的相互转换
//Fastjson测试
@RequestMapping(value = "/j6", produces = "application/json;charset=utf-8")
public String json6() throws JsonProcessingException {
ArrayList<User> list = new ArrayList<>();
User user1 = new User("身伤易逝", 18, "男");
User user2 = new User("情伤难合", 18, "男");
User user3 = new User("身伤易愈", 18, "男");
User user4 = new User("心伤难合", 18, "男");
list.add(user1);
list.add(user2);
list.add(user3);
list.add(user4);
//转化
String json = JSON.toJSONString(list);
return json;
}
总结: Fastjson只需要了解, 拿来就能用
Java对象 → JSON字符串 : JSON.toJSONString(list);
JSON字符串 → Java对象 : JSON.parseObject(list);
Java对象 → JSON对象 : JSON.toJSON(list);
JSON对象 → Java对象 : JSON.toJavaObject(list);