
本文介绍如何使用 java 高效、安全地将任意结构 json 中的所有键名(key)统一转为大写,兼容嵌套对象、数组等复杂结构,避免正则误匹配或破坏 json 格式。
本文介绍如何使用 java 高效、安全地将任意结构 json 中的所有键名(key)统一转为大写,兼容嵌套对象、数组等复杂结构,避免正则误匹配或破坏 json 格式。
在实际开发中,常需对接不同命名规范的系统(如前端传 camelCase,后端要求 UPPER_SNAKE_CASE 或全大写),而 JSON 键名大小写转换看似简单,却极易踩坑:直接用正则替换 ": " 前的单词会误伤字符串值、注释(若存在)、数字或布尔字面量;手动遍历 JsonNode 虽可靠但代码冗长,尤其面对多层嵌套数组与对象混合结构时易出错。
推荐采用语义化 JSON 转换方案——使用 Josson 库进行声明式键名转换。Josson 是轻量级 JSON 操作库,支持类似 JSONPath 的链式表达式,能自动处理嵌套、数组、对象混合结构,无需手动递归,且完全保持原始 JSON 语义完整性。
✅ 推荐方案:Josson 声明式转换(安全 & 简洁)
首先添加 Maven 依赖:
<dependency>
<groupId>com.octomix.josson</groupId>
<artifactId>josson</artifactId>
<version>1.6.1</version>
</dependency>然后使用以下核心逻辑完成转换:
import com.octomix.josson.Josson;
import com.fasterxml.jackson.databind.JsonNode;
public class JsonKeyUppercaser {
public static String uppercaseAllKeys(String jsonString) {
Josson josson = Josson.fromJsonString(jsonString);
JsonNode result = josson.getNode(
"flatten('.')" // 将嵌套结构展平为 key-path 形式(如 "Shipments[0].shipmentId")
+ ".entries()" // 转为键值对列表 [ { "key": "...", "value": ... } ]
+ ".map(key.upperCase()::value)" // 将每个 key 转大写,value 不变
+ ".mergeObjects()" // 合并回单个对象
+ ".unflatten('.')" // 按路径分隔符 '.' 还原嵌套结构
);
return result.toPrettyString();
}
// 示例调用
public static void main(String[] args) {
String input = "{
" +
" "transactionId": 181,
" +
" "Shipments": [
" +
" {
" +
" "shipmentId": 2,
" +
" "picklistId": "24RZ",
" +
" "ExtOrderId": "23-127",
" +
" "boxType": "120"
" +
" }
" +
" ]
" +
"}";
System.out.println(uppercaseAllKeys(input));
}
}输出结果严格符合预期:
{
"TRANSACTIONID" : 181,
"SHIPMENTS" : [ {
"SHIPMENTID" : 2,
"PICKLISTID" : "24RZ",
"EXTORDERID" : "23-127",
"BOXTYPE" : "120"
} ]
}⚠️ 重要注意事项
- 勿用正则直接替换:类似 replaceAll("("[^"]+")\s*:", "$1.toUpperCase():") 在字符串含冒号(如 URL、时间戳)或转义引号时必然失败,且无法区分 key 与 value;
- Josson 优势明确:flatten() 和 unflatten() 自动处理数组索引(如 [0])、嵌套层级、空对象/数组,无须手写递归逻辑;
- 性能与可靠性平衡:Josson 基于 Jackson 构建,解析严谨,适用于生产环境;若项目已用 Jackson,也可自行实现递归遍历(见下方备选思路),但 Josson 代码量减少 80% 以上;
- 扩展性提示:如需转为 SNAKE_CASE 或其他格式,仅需将 key.upperCase() 替换为自定义函数(如 key.camelToSnake().upperCase()),Josson 支持 Java 方法引用。
✅ 备选方案(纯 Jackson 实现,适合无额外依赖场景)
若受限于技术栈不允许引入新库,可基于 Jackson 的 JsonNode 手动递归处理:
public static JsonNode uppercaseKeys(JsonNode node) {
if (node.isObject()) {
ObjectNode objectNode = (ObjectNode) node;
Iterator<Map.Entry<String, JsonNode>> fields = objectNode.fields();
ObjectNode newNode = JsonNodeFactory.instance.objectNode();
while (fields.hasNext()) {
Map.Entry<String, JsonNode> entry = fields.next();
String upperKey = entry.getKey().toUpperCase();
newNode.set(upperKey, uppercaseKeys(entry.getValue()));
}
return newNode;
} else if (node.isArray()) {
ArrayNode arrayNode = (ArrayNode) node;
ArrayNode newArray = JsonNodeFactory.instance.arrayNode();
for (JsonNode element : arrayNode) {
newArray.add(uppercaseKeys(element));
}
return newArray;
} else {
return node; // 原始值(string/number/boolean/null)不修改
}
}调用方式:JsonNode result = uppercaseKeys(objectMapper.readTree(jsonString));
总结:对于 JSON 键名批量大写需求,优先选用 Josson 的声明式方案——语义清晰、代码简洁、健壮性强;仅在强约束下才采用 Jackson 手动递归。切忌依赖正则做 JSON 结构操作,这是反模式且不可维护的实践。










