JSON格式学完这篇就够啦
目录
JSON简介
什么是JSON
JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式,具有以下特点:
- 轻量级: 相比XML更简洁,数据冗余少
- 易读性: 人类和机器都容易理解
- 语言无关: 支持多种编程语言
- 自描述: 数据结构清晰明了
- 标准化: 遵循RFC 7159标准
JSON的优势
// JSON格式 - 简洁明了
{
"name": "张三",
"age": 25,
"skills": ["Java", "Spring", "MySQL"]
}
// 对比XML格式 - 冗长复杂
<person>
<name>张三</name>
<age>25</age>
<skills>
<skill>Java</skill>
<skill>Spring</skill>
<skill>MySQL</skill>
</skills>
</person>
应用场景
- API接口: RESTful API数据交换
- 配置文件: 应用配置、环境配置
- 数据存储: NoSQL数据库、缓存
- 前后端通信: 浏览器与服务器数据交互
- 日志记录: 结构化日志数据
格式规则
1. 基本数据类型
字符串 (String)
{
"name": "张三",
"description": "这是一个\"引号\"示例",
"path": "C:\\Users\\admin",
"unicode": "\u4e2d\u6587"
}
数字 (Number)
{
"integer": 42,
"negative": -17,
"decimal": 3.14159,
"scientific": 1.23e-4,
"zero": 0
}
布尔值 (Boolean)
{
"active": true,
"deleted": false
}
空值 (null)
{
"optional": null,
"notSet": null
}
2. 复合数据类型
对象 (Object)
{
"user": {
"id": 1001,
"profile": {
"firstName": "张",
"lastName": "三"
}
}
}
数组 (Array)
{
"numbers": [1, 2, 3, 4, 5],
"strings": ["a", "b", "c"],
"mixed": [1, "two", true, null],
"nested": [
[1, 2],
[3, 4]
]
}
3. 语法规则
基本规则
{
"key": "value", // 键值对用冒号分隔
"array": [1, 2, 3], // 数组元素用逗号分隔
"object": { // 对象属性用逗号分隔
"a": 1,
"b": 2
}
}
注意事项
- 键名必须用双引号包围
- 字符串值必须用双引号包围
- 最后一个元素后面不能有逗号
- 不支持注释
- 不支持函数
使用技巧
1. 数据组织技巧
扁平化结构
// ❌ 不推荐:嵌套过深
{
"company": {
"department": {
"team": {
"member": {
"name": "张三",
"role": "开发工程师"
}
}
}
}
}
// ✅ 推荐:扁平化结构
{
"companyName": "XX公司",
"departmentName": "技术部",
"teamName": "开发团队",
"memberName": "张三",
"memberRole": "开发工程师"
}
数组优化
// ❌ 不推荐:对象数组,重复键名
[
{"id": 1, "name": "张三", "age": 25},
{"id": 2, "name": "李四", "age": 30},
{"id": 3, "name": "王五", "age": 28}
]
// ✅ 推荐:键值对数组,减少重复
{
"ids": [1, 2, 3],
"names": ["张三", "李四", "王五"],
"ages": [25, 30, 28]
}
2. 性能优化技巧
减少数据量
// ❌ 不推荐:包含不必要的数据
{
"user": {
"id": 1001,
"name": "张三",
"email": "zhangsan@example.com",
"phone": "13800138000",
"address": "北京市朝阳区...",
"createTime": "2024-01-01T00:00:00Z",
"updateTime": "2024-01-01T00:00:00Z",
"status": 1,
"deleted": false
}
}
// ✅ 推荐:只返回必要字段
{
"user": {
"id": 1001,
"name": "张三",
"email": "zhangsan@example.com"
}
}
使用数字替代字符串
// ❌ 不推荐:使用字符串表示状态
{
"status": "active",
"type": "user"
}
// ✅ 推荐:使用数字表示状态
{
"status": 1, // 1: active, 0: inactive
"type": 1 // 1: user, 2: admin
}
3. 可读性技巧
合理缩进
{
"api": {
"version": "v1",
"endpoints": {
"users": {
"get": "/api/v1/users",
"post": "/api/v1/users",
"put": "/api/v1/users/{id}",
"delete": "/api/v1/users/{id}"
}
}
}
}
使用有意义的键名
// ❌ 不推荐:键名不清晰
{
"d": "2024-01-01",
"n": "张三",
"a": 25
}
// ✅ 推荐:键名清晰明确
{
"date": "2024-01-01",
"name": "张三",
"age": 25
}
---
## 重难点分析
### 1. 数据类型转换
#### 数字精度问题
```json
// JavaScript中的精度问题
{
"price": 0.1 + 0.2 // 结果: 0.30000000000000004
}
// 解决方案:使用字符串表示金额
{
"price": "0.30"
}
大整数处理
// ❌ 不推荐:大整数可能丢失精度
{
"id": 9007199254740991
}
// ✅ 推荐:使用字符串表示大整数
{
"id": "9007199254740991"
}
2. 特殊字符处理
转义字符
{
"text": "第一行\n第二行", // 换行符
"path": "C:\\Users\\admin", // 反斜杠
"quote": "他说:\"你好!\"", // 引号
"unicode": "\u4e2d\u6587" // Unicode字符
}
控制字符
// 需要转义的控制字符
{
"tab": "制表符\t",
"backspace": "退格符\b",
"formfeed": "换页符\f",
"carriage": "回车符\r"
}
3. 嵌套结构处理
深度嵌套问题
// 避免过深的嵌套
{
"level1": {
"level2": {
"level3": {
"level4": {
"level5": {
"value": "too deep!"
}
}
}
}
}
}
循环引用问题
// Java中避免循环引用
public class User {
private String name;
private List<Order> orders;
// 使用@JsonManagedReference和@JsonBackReference
@JsonManagedReference
public List<Order> getOrders() {
return orders;
}
}
public class Order {
private String orderNo;
private User user;
@JsonBackReference
public User getUser() {
return user;
}
}
---
## 面试高频点
### 1. 基础概念
#### Q: JSON和XML的区别?
**A:**
- **可读性**: JSON更简洁,XML更冗长
- **解析性能**: JSON解析更快
- **数据类型**: JSON支持基本数据类型,XML都是字符串
- **注释**: JSON不支持注释,XML支持
- **命名空间**: JSON不支持,XML支持
#### Q: JSON的优缺点?
**A:**
**优点:**
- 轻量级,数据冗余少
- 解析简单,支持多种语言
- 可读性好
**缺点:**
- 不支持注释
- 不支持函数
- 数据类型有限
- 不支持循环引用
### 2. 技术实现
#### Q: 如何避免JSON序列化时的循环引用?
**A:**
```java
// 方法1: 使用注解
@JsonManagedReference
@JsonBackReference
// 方法2: 使用@JsonIgnore
@JsonIgnore
private User user;
// 方法3: 自定义序列化器
@JsonSerialize(using = CustomSerializer.class)
Q: JSON和Java对象的映射方式?
A:
// 方式1: Jackson (推荐)
ObjectMapper mapper = new ObjectMapper();
User user = mapper.readValue(jsonString, User.class);
String json = mapper.writeValueAsString(user);
// 方式2: Gson
Gson gson = new Gson();
User user = gson.fromJson(jsonString, User.class);
String json = gson.toJson(user);
// 方式3: FastJson
User user = JSON.parseObject(jsonString, User.class);
String json = JSON.toJSONString(user);
3. 性能优化
Q: 如何优化JSON的解析性能?
A:
- 使用流式解析(Jackson Streaming API)
- 缓存ObjectMapper实例
- 使用更快的库(如FastJson)
- 减少不必要的数据传输
- 使用压缩(gzip)
Q: 大量JSON数据的处理策略?
A:
// 流式处理
JsonParser parser = mapper.getFactory().createParser(jsonFile);
while (parser.nextToken() != null) {
// 逐个处理token
}
// 分批处理
List<String> batches = splitIntoBatches(jsonData, batchSize);
for (String batch : batches) {
processBatch(batch);
}
---
## Java项目应用场景
### 1. Spring Boot应用
#### RESTful API
```java
@RestController
@RequestMapping("/api/users")
public class UserController {
@PostMapping
public ResponseEntity<User> createUser(@RequestBody User user) {
// @RequestBody自动将JSON转换为User对象
User savedUser = userService.save(user);
return ResponseEntity.ok(savedUser);
}
@GetMapping("/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
User user = userService.findById(id);
return ResponseEntity.ok(user);
}
}
2. 微服务架构
服务间通信
// 使用RestTemplate发送JSON请求
@Service
public class UserService {
@Autowired
private RestTemplate restTemplate;
public Order createOrder(Long userId, OrderRequest request) {
String url = "http://order-service/api/orders";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<OrderRequest> entity = new HttpEntity<>(request, headers);
ResponseEntity<Order> response = restTemplate.postForEntity(url, entity, Order.class);
return response.getBody();
}
}
3. 数据持久化
MongoDB文档
@Document(collection = "users")
public class User {
@Id
private String id;
private String name;
private String email;
// 嵌套文档
private Address address;
// 数组字段
private List<String> roles;
// 动态字段
private Map<String, Object> attributes;
}
4. 前端交互
AJAX请求
@RestController
public class AjaxController {
@PostMapping("/ajax/user")
public Map<String, Object> handleAjaxRequest(@RequestBody Map<String, Object> request) {
Map<String, Object> response = new HashMap<>();
try {
// 处理请求数据
String name = (String) request.get("name");
Integer age = (Integer) request.get("age");
// 返回响应
response.put("success", true);
response.put("message", "处理成功");
response.put("data", Arrays.asList(name, age));
} catch (Exception e) {
response.put("success", false);
response.put("message", "处理失败: " + e.getMessage());
}
return response;
}
}
总结
JSON作为现代Web开发中最重要的数据交换格式,掌握其使用技巧和最佳实践对于Java开发者来说至关重要。通过合理的数据组织、性能优化和错误处理,可以构建高效、可维护的JSON数据处理系统。
在实际项目中,建议:
- 选择合适的JSON库(推荐Jackson)
- 遵循数据设计原则(扁平化、标准化)
- 注意性能优化(流式处理、缓存)
- 做好错误处理(验证、异常处理)
- 保持代码可读性(清晰的结构、有意义的命名)
1万+

被折叠的 条评论
为什么被折叠?



