使用@JsonAnyGetter时,PropertyNamingStrategy被忽略

时间:2015-05-27 12:34:16

标签: java json jackson spring-boot

情境:

使用Jackson 2.4.5我有一个动态bean被序列化为JSON,它可以将一些状态存储在' optional'内部映射中的属性,并在返回此映射的访问器方法上使用@JsonAnyGetter,例如:

public class DynamicJsonView {

private final Map<String, Object> optionalProperties = new HashMap<>();

private final String rqdProperty = "blah";

public String getRqdProperty() {
    return rqdProperty;
}

public DynamicJsonView() {
    optionalProperties.put("PROP_1", "value 1");
    optionalProperties.put("PROP_2", "value 2");
    optionalProperties.put("PROP_3", "value 3");
    // etc - in reality populated from another map
}

@JsonAnyGetter
public Map<String, Object> any() {
    return Collections.unmodifiableMap(optionalProperties);
} 
}

注意地图键是UPPER_CASE。当我们设置ObjectMapper时,我们设置以下命名策略将属性转换为小写(并用snake_case替换camelCase),例如:

objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);

问题:

这与普通的java属性完全一样,即上例中的rqdProperty转换为JSON序列化形式的rqd_property,但命名策略似乎被地图忽略了。属性&#39;,大写键未经修改。调试了jackson LowerCaseWithUnderscoresStrategy#translate方法并观察了在对象被序列化时传入的input参数值,似乎密钥永远不会通过命名策略传递。

显而易见的解决方法是预处理地图密钥并将它们全部转换为小写,但我想知道在属性命名策略方面是否存在我缺少的东西,或者这是否是只是图书馆的限制?

1 个答案:

答案 0 :(得分:1)

这是设计的,因为NamingStrategy仅适用于实际的具体属性,而不适用于Map键,或者&#34;任何&#34;属性。

但是如果为任何属性包含名称修改的能力听起来是个好主意,你可以请求一个新功能:它可以通过@JsonAnySetter的标志启用(例如):

https://github.com/FasterXML/jackson-databind/issues/