Jackson ObjectMapper LowerCaseStrategy小写命名策略不生效问题
配置不生效的核心原因
- 第一点:
ObjectMapper声明为静态变量,但属性命名策略的配置写在了类构造函数中。静态变量在类加载阶段就完成初始化,构造函数仅在类实例化时才会执行,只要你没有实例化Example类,命名策略的配置就永远不会生效。 - 第二点:Jackson 的
PropertyNamingStrategy仅对 Java Bean 的序列化、反序列化流程生效,你当前直接使用readTree方法读取为JsonNode树模型的场景下,默认不会触发字段名的转换规则。
修复方案
方案1:调整初始化时机+映射为自定义Java Bean(推荐)
如果可以根据API返回结构定义对应的Java实体类,直接使用实体类接收反序列化结果,全局命名策略就会自动生效,序列化输出给下游系统时所有字段名都会转为小写:
package com.example; import java.io.IOException; import java.net.URL; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategies; public class Example { // 改为在静态初始化块中配置ObjectMapper,类加载时即生效 private static final ObjectMapper mapper; static { mapper = new ObjectMapper(); mapper.setPropertyNamingStrategy(PropertyNamingStrategies.LOWER_CASE); } // 传入自定义实体类Class,反序列化时自动转换字段名 public <T> T fetchData(String url, Class<T> clazz) throws IOException{ return mapper.readValue(new URL(url), clazz); } }
后续你把实体类序列化为JSON传给下游系统时,所有字段会自动输出为全小写格式。
方案2:保留JsonNode场景,手动递归转换字段名
如果必须使用JsonNode结构,需要额外写递归方法遍历所有字段名转为小写:
package com.example; import java.io.IOException; import java.net.URL; import java.util.Iterator; import java.util.Map; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategies; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; public class Example { private static final ObjectMapper mapper; static { mapper = new ObjectMapper(); mapper.setPropertyNamingStrategy(PropertyNamingStrategies.LOWER_CASE); } public JsonNode fetchData(String url) throws IOException{ JsonNode originalNode = mapper.readTree(new URL(url)); return toLowerCaseFieldNameNode(originalNode); } // 递归转换所有字段名为小写 private JsonNode toLowerCaseFieldNameNode(JsonNode node) { if (node.isObject()) { ObjectNode newObj = mapper.createObjectNode(); Iterator<Map.Entry<String, JsonNode>> fieldIter = node.fields(); while (fieldIter.hasNext()) { Map.Entry<String, JsonNode> field = fieldIter.next(); newObj.set(field.getKey().toLowerCase(), toLowerCaseFieldNameNode(field.getValue())); } return newObj; } else if (node.isArray()) { ArrayNode newArr = mapper.createArrayNode(); for (JsonNode item : node) { newArr.add(toLowerCaseFieldNameNode(item)); } return newArr; } return node; } }
内容的提问来源于stack exchange,提问作者Brady Shober
相关产品推荐
相关产品推荐

