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]  # 输出:Alice

5. 处理复杂对象

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.biz

8. 注意事项

  • 编码
  • JSON 默认使用 UTF-8,确保输入字符串编码正确:
    ruby JSON.parse(str, encoding: 'UTF-8')
  • 处理非 UTF-8 数据时,需转码:
    ruby str.encode('UTF-8', 'ISO-8859-1')
  • 性能
  • 大型 JSON 数据解析可能较慢,考虑流式解析(JSON::Stream gem)。
  • 缓存频繁使用的 JSON 结果。
  • 安全性
  • 解析外部 JSON 时,验证数据格式,防止注入攻击。
  • 避免序列化敏感数据(如密码)。
  • 对象支持
  • 仅支持基本类型(字符串、数字、布尔值、数组、哈希、null)。
  • 自定义对象需定义 to_json 方法。
  • 调试
  • 使用 pretty_generate 检查 JSON 结构。
  • 捕获 JSON::ParserError 定位错误。
  • 现代替代
  • Rails 的 ActiveSupport::JSON 提供额外功能。
  • 复杂 API 推荐使用 httpartyfaraday

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.generateJSON.parse 提供高效的 JSON 序列化和反序列化功能,支持哈希、数组等基本类型。结合 pretty_generatesymbolize_names 优化开发体验。注意编码一致性、异常处理和安全性,适合 API 数据处理、配置文件管理等场景。复杂 Web 应用可结合 httparty 或 Rails 增强功能。

如果你需要更复杂的 JSON 示例(如流式解析、复杂对象序列化)或有其他问题,请告诉我!

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注