JsonObjectView 函数手册
C++ 后端服务器框架JsonObjectView 函数手册
CHAPTER 19

JsonObjectView 函数手册

4 分钟阅读 · 982 字

依据源码:include/JsonObjectView.h。
该模块为 header-only(无独立 cpp),所有函数均内联定义在头文件中。


0. 模块定位

JsonObjectView 是 JsonValue 的轻量包装访问器,目标是:

  • JSON 文本一次解析后进行链式键访问
  • 提供统一字符串/数字读取接口
  • 提供 object 的浅层导出(unordered_map)

它不替代 JsonValue,而是“读取体验层”。


1. 数据成员

JsonValue node_;(私有)

  • 保存当前视图指向的 JSON 节点值(对象、数组或标量)。
  • 视图不是引用语义,而是值语义(内部持有一份 JsonValue)。

2. 构造函数

2.1 JsonObjectView() = default

  • 默认构造一个空视图。
  • 空视图底层 node_ 为 JsonValue 默认值(通常是 NULL_TYPE)。

2.2 explicit JsonObjectView(JsonValue v)

  • 参数按值传入,再 std::move(v) 到 node_。
  • 用于从已有 JsonValue 构造视图。

3. 解析入口

static JsonObjectView parse(const std::string& json)

  • 作用:将 JSON 文本解析成根视图。

执行步骤

  1. JsonValue v;
  2. v.fromJson(json);
  3. return JsonObjectView(std::move(v));

异常语义

  • 若 fromJson 解析失败,异常向上传播(本函数不捕获)。

面试点

  • 该函数只负责“建根视图”,并不限制根节点必须是对象;数组/标量也允许。
  • 但 operator[] 仅对对象类型有效。

4. 键访问

JsonObjectView operator[](const std::string& key) const

  • 作用:在当前节点为对象时取子键,返回新视图。

执行步骤

  1. 若 node_.getType() != JsonValue::OBJECT:
    • 返回空视图 {}
  2. const auto obj = node_.asObject();
  3. it = obj.find(key)
  4. 若未找到:
    • 返回空视图 {}
  5. 找到:
    • return JsonObjectView(it->second);

语义特点

  • 非对象节点访问键不会抛异常,返回空视图(容错式 API)。
  • 访问链中任何一步失败都会传递为空视图。

性能注意

  • asObject() 返回对象副本,operator[] 每次调用会复制一层 map。
  • 深链访问在大对象上可能有额外开销。

5. 原始值与拷贝接口

5.1 const JsonValue& raw() const

  • 返回内部 node_ 的常量引用。
  • 适合需要读取底层完整类型信息的场景。

5.2 JsonValue copy() const

  • 返回 node_ 的值拷贝。
  • 适合调用方需要独立副本进行后续修改。

6. 类型读取接口

6.1 std::string asString() const

  • 语义与历史 jsonGetString 保持一致:
    • 若 node_ 是 STRING:返回原字符串
    • 否则:返回 node_.toJson()

说明

  • 非字符串不会返回空,而是 JSON 序列化文本(例如数字返回 "123" 的文本形式 123)。

6.2 int asInt(int defaultValue = 0) const

  • 转换规则:
    1. NUMBER:static_cast<int>(node_.asNumber())
    2. STRING:尝试 std::stoi(node_.asString())
    3. 其他类型:返回 defaultValue
    4. stoi 抛异常时:返回 defaultValue

注意

  • NUMBER -> int 为截断转换(小数会截断)。

6.3 double asNumber(double defaultValue = 0.0) const

  • 转换规则:
    1. NUMBER:返回 asNumber()
    2. STRING:尝试 std::stod(node_.asString())
    3. 其他类型或解析失败:返回 defaultValue

6.4 bool isObject() const

  • 判断当前节点是否对象类型:node_.getType() == JsonValue::OBJECT。

7. 对象导出接口

std::unordered_map<std::string, JsonValue> asUnorderedMap() const

  • 作用:将当前对象节点浅拷贝导出为 unordered_map。

执行步骤

  1. 创建空 out
  2. 若当前非对象:返回空 out
  3. 遍历 node_.asObject() 的键值对
  4. out.emplace(k, v)
  5. 返回 out

语义

  • 仅浅层导出;嵌套对象仍以 JsonValue 形式存在。
  • map -> unordered_map 转换后键顺序不保证。

8. 常见使用模式(面试表达)

auto root = JsonObjectView::parse(jsonText);
std::string name = root["user"]["name"].asString();
int age = root["user"]["age"].asInt(-1);

若任一层不存在或类型不符,最终返回默认值/空视图,不会因键缺失抛异常。


9. 边界与改进建议

优点

  • API 非常轻量,业务读取代码简洁
  • 键缺失容错友好
  • 与 JsonValue 完整兼容

限制

  • 值语义导致对象复制开销(asObject() + JsonValue 复制)
  • 仅支持对象键访问,不支持数组下标访问器
  • 空视图与 JSON null 语义需要业务侧区分

可改进方向

  • 引入引用视图(const JsonValue*)减少复制
  • 增加 operator[](size_t index) 以支持数组
  • 增加 has(key) / isNull() / type() 辅助接口

下一模块(顺序)

JWT → docs/modules/detail/JWT_FUNCTIONS.md

全部章节