Ruby JSON
在 Ruby 中,JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,常用于 Web 应用程序的 API 数据传输、配置文件存储等。Ruby 提供了内置的 json 库来解析和生成 JSON 数据,简单高效。以下是对 Ruby JSON 处理的中文讲解,涵盖核心概念、解析与生成 JSON、常用方法、示例代码及注意事项,力求简洁清晰。
1. JSON 简介
JSON 是一种基于文本的格式,用于表示结构化数据,支持对象(键值对)、数组、字符串、数字、布尔值和 null。Ruby 的 json 库提供了将 Ruby 对象转换为 JSON 字符串(序列化)以及将 JSON 字符串解析为 Ruby 对象(反序列化)的功能。
特点:
- 跨语言支持,适合 API 和数据交换。
- 轻量,易于阅读和解析。
- Ruby 的 json库是标准库,无需额外安装。
2. 安装与引入
json 库是 Ruby 标准库的一部分,无需安装,直接引入:
require 'json'验证:
puts JSON::VERSION  # 输出:2.6.3(示例版本,视 Ruby 版本而定)3. 生成 JSON(序列化)
将 Ruby 对象(如哈希、数组)转换为 JSON 字符串。
基本方法
- JSON.generate(obj):将对象转换为 JSON 字符串。
- obj.to_json:对象调用- to_json方法,生成 JSON。
示例
require 'json'
# Ruby 哈希
data = {
  name: "Alice",
  age: 30,
  hobbies: ["reading", "coding"],
  address: { city: "Beijing", country: "China" }
}
# 生成 JSON
json_str = JSON.generate(data)
puts json_str
# 简写
puts data.to_json输出:
{"name":"Alice","age":30,"hobbies":["reading","coding"],"address":{"city":"Beijing","country":"China"}}格式化输出
使用 JSON.pretty_generate 生成带缩进的 JSON,便于阅读:
puts JSON.pretty_generate(data)输出:
{
  "name": "Alice",
  "age": 30,
  "hobbies": [
    "reading",
    "coding"
  ],
  "address": {
    "city": "Beijing",
    "country": "China"
  }
}4. 解析 JSON(反序列化)
将 JSON 字符串转换为 Ruby 对象(通常是哈希或数组)。
基本方法
- JSON.parse(str):解析 JSON 字符串,返回 Ruby 对象。
- 选项:
- symbolize_names: true:将键转换为符号。
- allow_nan: true:允许解析 NaN、Infinity 等非标准值。
示例
require 'json'
json_str = '{"name":"Alice","age":30,"hobbies":["reading","coding"]}'
# 解析为哈希(键为字符串)
data = JSON.parse(json_str)
puts data["name"]  # 输出:Alice
# 解析为哈希(键为符号)
data = JSON.parse(json_str, symbolize_names: true)
puts data[:name]  # 输出:Alice5. 处理复杂对象
Ruby 的 json 库支持大多数 Ruby 对象,但自定义对象需实现 to_json 方法。
自定义对象
require 'json'
class User
  def initialize(name, age)
    @name = name
    @age = age
  end
  def to_json(*args)
    { name: @name, age: @age }.to_json(*args)
  end
end
user = User.new("Alice", 30)
puts JSON.generate(user)输出:
{"name":"Alice","age":30}6. 异常处理
解析 JSON 时可能因格式错误抛出异常,需妥善处理。
require 'json'
begin
  JSON.parse("invalid json")  # 无效 JSON
rescue JSON::ParserError => e
  puts "解析错误: #{e.message}"
end输出:
解析错误: unexpected token at 'invalid json'常见异常:
- JSON::ParserError:JSON 格式错误。
- JSON::NestingError:嵌套层次过深。
- TypeError:尝试序列化不支持的对象类型。
7. 结合 Web 应用
JSON 常用于 Web API(如 RESTful 服务)。以下示例展示如何结合 net/http 获取和解析 JSON。
require 'json'
require 'net/http'
uri = URI('https://jsonplaceholder.typicode.com/users/1')
response = Net::HTTP.get(uri)
user = JSON.parse(response, symbolize_names: true)
puts "Name: #{user[:name]}, Email: #{user[:email]}"输出(示例):
Name: Leanne Graham, Email: Sincere@april.biz8. 注意事项
- 编码:
- JSON 默认使用 UTF-8,确保输入字符串编码正确:ruby JSON.parse(str, encoding: 'UTF-8')
- 处理非 UTF-8 数据时,需转码:ruby str.encode('UTF-8', 'ISO-8859-1')
- 性能:
- 大型 JSON 数据解析可能较慢,考虑流式解析(JSON::Streamgem)。
- 缓存频繁使用的 JSON 结果。
- 安全性:
- 解析外部 JSON 时,验证数据格式,防止注入攻击。
- 避免序列化敏感数据(如密码)。
- 对象支持:
- 仅支持基本类型(字符串、数字、布尔值、数组、哈希、null)。
- 自定义对象需定义 to_json方法。
- 调试:
- 使用 pretty_generate检查 JSON 结构。
- 捕获 JSON::ParserError定位错误。
- 现代替代:
- Rails 的 ActiveSupport::JSON提供额外功能。
- 复杂 API 推荐使用 httparty或faraday。
9. 综合示例
以下示例实现一个简单的 JSON 数据处理器,结合文件读写和 HTTP 请求。
require 'json'
require 'net/http'
# 保存用户数据到 JSON 文件
users = [
  { id: 1, name: "Alice", age: 30 },
  { id: 2, name: "Bob", age: 25 }
]
# 写入文件
File.write('users.json', JSON.pretty_generate(users))
puts "已保存到 users.json"
# 读取并解析文件
data = JSON.parse(File.read('users.json'), symbolize_names: true)
puts "读取用户: #{data.map { |u| u[:name] }.join(', ')}"
# 从 API 获取数据
begin
  uri = URI('https://jsonplaceholder.typicode.com/users')
  response = Net::HTTP.get(uri)
  api_users = JSON.parse(response, symbolize_names: true)
  puts "API 用户: #{api_users.first[:name]}"
rescue JSON::ParserError => e
  puts "API 解析错误: #{e.message}"
rescue => e
  puts "其他错误: #{e.message}"
end输出:
已保存到 users.json
读取用户: Alice, Bob
API 用户: Leanne Graham保存的 users.json:
[
  {
    "id": 1,
    "name": "Alice",
    "age": 30
  },
  {
    "id": 2,
    "name": "Bob",
    "age": 25
  }
]10. 总结
Ruby 的 json 库通过 JSON.generate 和 JSON.parse 提供高效的 JSON 序列化和反序列化功能,支持哈希、数组等基本类型。结合 pretty_generate 和 symbolize_names 优化开发体验。注意编码一致性、异常处理和安全性,适合 API 数据处理、配置文件管理等场景。复杂 Web 应用可结合 httparty 或 Rails 增强功能。
如果你需要更复杂的 JSON 示例(如流式解析、复杂对象序列化)或有其他问题,请告诉我!