JSON
1. JSON基础
1. 前后端分离
-
后端: 部署后端, 提供接口, 提供数据
-
前端: 独立部署, 负责渲染后端的数据
-
JSON负责将前后端连接起来
2. JSON概述
- JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式,目前使用特别广泛。
- 采用完全独立于编程语言的文本格式来存储和表示数据。
- 简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。
- 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
在 JavaScript 语言中,一切都是对象。因此,任何JavaScript 支持的类型都可以通过 JSON 来表示,例如字符串、数字、对象、数组等。看看他的要求和语法格式:
- 对象表示为键值对,数据由逗号分隔
- 花括号保存对象
- 方括号保存数组
JSON 键值对是用来保存 JavaScript 对象的一种方式,和 JavaScript 对象的写法也大同小异,键/值对组合中的键名写在前面并用双引号 "" 包裹,使用冒号 : 分隔,然后紧接着值
2. JSON和JavaScript对象互相转换
JavaScript转JSON, 用JSON.stringify()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript">
//编写一个JavaScript对象
let user = {
name : "wang_sky",
age : 3,
sex: "男"
};
//将js对象转换为json对象
let json = JSON.stringify(user);
console.log(json);
</script>
</head>
<body>
</body>
</html>
JSON转JavaScript, 用JSON.parse()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript">
//编写一个JavaScript对象
let user = {
name : "wang_sky",
age : 3,
sex: "男"
};
//将js对象转换为json对象
let json = JSON.stringify(user);
console.log(json);
console.log(user);
//将json对象转换为JavaScript对象
let parse = JSON.parse(json);
console.log(parse);
</script>
</head>
<body>
</body>
</html>
3. Jackson
1. 导入依赖
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.2</version>
</dependency>
2. 编写controller
package com.wang.controller;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wang.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class UserController {
//@ResponseBody: 它就不会走视图解析器, 会直接返回一个字符串到当前页面!
@ResponseBody
@RequestMapping("/j1")
public String json1() throws JsonProcessingException {
//jackson, ObjectMapper
ObjectMapper mapper = new ObjectMapper();
//创建一个对象
User user = new User("wang_sky_1", 3, "男");
String string = mapper.writeValueAsString(user);
return string;
}
}
结果为
{"name":"wang_sky_1","age":3,"sex":"?"}
3. 解决乱码
发现出现了乱码问题,我们需要设置一下他的编码格式为utf-8,以及它返回的类型;
通过@RequestMaping的produces属性来实现,修改下代码
//produces:指定响应体返回类型和编码
@RequestMapping(value = "/j1",produces = "application/json;charset=utf-8")
4. 代码优化
1. 统一解决乱码
在spring配置文件中配置如下
<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>
2. 两个注解
- @RestController: 在类上, 表示这个controller不走视图解析器, 直接返回字符串
- @ResponseBody: 在方法上, 与@RestController作用一致
- 以上两个注解用来做前后端分离传递JSON
3. 集合
@ResponseBody
@RequestMapping(value = "/j2")
public String json2() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
ArrayList<User> users = new ArrayList<>();
User user1 = new User("wang_sky_1", 3, "男");
User user2 = new User("wang_sky_2", 4, "男");
User user3 = new User("wang_sky_3", 5, "男");
User user4 = new User("wang_sky_4", 6, "男");
users.add(user1);
users.add(user2);
users.add(user3);
users.add(user4);
String user = mapper.writeValueAsString(users);
return user;
}
结果
[{"name":"wang_sky_1","age":3,"sex":"男"},{"name":"wang_sky_2","age":4,"sex":"男"},{"name":"wang_sky_3","age":5,"sex":"男"},{"name":"wang_sky_4","age":6,"sex":"男"}]
4. 时间
1. 使用java自定义日期格式
@RequestMapping(value = "/j3")
public String json3() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
Date date = new Date();
//自定义日期格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return mapper.writeValueAsString(sdf.format(date));
}
2. 使用ObjectMapper格式化输出
@RequestMapping(value = "/j4")
public String json4() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
//使用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();
return mapper.writeValueAsString(date);
}
3. 利用工具类
- 工具类
注意: 此处要注意两点:
- 写成静态方法方便调用
- 方法重载时, 可以从方法签名全的倒着写, 缺省的参数在重载的方法中设定默认值!
package com.wang.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 object) {
return getJson(object, "yyyy-MM-dd HH:mm:ss");
}
//这里写成静态方法, 方便调用(不用new 对象)
public static String getJson(Object object, String dateFormat) {
ObjectMapper mapper = new ObjectMapper();
//使用ObjectMapper格式化输出, 关闭时间戳
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
//自定义日期格式
SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
mapper.setDateFormat(sdf);
try {
return mapper.writeValueAsString(object);
} catch (JsonProcessingException e) {
e.printStackTrace();
return null;
}
}
}
- 调用
@RequestMapping("/j5")
public String json5() {
String dateFormat = "yyyy-MM-dd HH:mm:ss";
return JsonUtils.getJson(new Date(), dateFormat);
}
5. JSON总结
-
导入jackson包
-
配置解决乱码问题
-
返回JSON: 使用@RestController(类上)或者@RequestBody(方法上)
-
new一个ObjectMapper()
-
利用new出的mapper, 调用writeValueAsString(对象)
-
即可得到由对象转换为的JSON
4. FastJSON
1. 导入依赖
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.73</version>
</dependency>
2. fastjson 三个主要的类:
1. JSONObject 代表 json 对象
- JSONObject实现了Map接口, 猜想 JSONObject底层操作是由Map实现的。
- JSONObject对应json对象,通过各种形式的get()方法可以获取json对象中的数据,也可利用诸如size(),isEmpty()等方法获取"键:值"对的个数和判断是否为空。其本质是通过实现Map接口并调用接口中的方法完成的。
2. JSONArray 代表 json 对象数组
- 内部是有List接口中的方法来完成操作的。
3. JSON代表 JSONObject和JSONArray的转化
- JSON类源码分析与使用
- 仔细观察这些方法,主要是实现json对象,json对象数组,javabean对象,json字符串之间的相互转化。
3. 测试
@RequestMapping(value = "/j6")
public String json6() throws JsonProcessingException {
ArrayList<User> users = new ArrayList<>();
User user1 = new User("wang_sky_1", 3, "男");
User user2 = new User("wang_sky_2", 4, "男");
User user3 = new User("wang_sky_3", 5, "男");
User user4 = new User("wang_sky_4", 6, "男");
users.add(user1);
users.add(user2);
users.add(user3);
users.add(user4);
return JSON.toJSONString(users);
}