JSON格式学完这篇就够啦

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: JSONXML的区别?
**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数据处理系统。

在实际项目中,建议:

  1. 选择合适的JSON库(推荐Jackson)
  2. 遵循数据设计原则(扁平化、标准化)
  3. 注意性能优化(流式处理、缓存)
  4. 做好错误处理(验证、异常处理)
  5. 保持代码可读性(清晰的结构、有意义的命名)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值