我可以在对象之外获得等效于 @JsonAnySetter 的功能吗?

Can I get the equivalent of @JsonAnySetter functionality, outside of the object?

我在一个被 Jackson 反序列化的对象中有这个定义:

public class ImportantInterfaceObject {

    @JsonAnySetter
    private Map<String, String> unmapped = new HashMap<String, String>();

    // ... other stuff omitted for clarity ...
}

这在允许 unmapped 成员捕获要根据要求和最佳实践进行处理和处理的输入中的任何意外值方面非常有效。

但是,它用这个额外的包袱污染了 ImportantInterfaceObject 定义。

有没有办法实现与 @JsonAnySetter 相同的效果,但在 Jackson 对象生命周期的另一个级别?

例如,

ObjectMapper objectMapper = new ObjectMapper();

// pseudo-code, this doesn't exist
objectMapper.setAnyHandler((key,value) -> doSomething(...));

// back to normal valid code now
JsonNode json = objectMapper.readTree(input);

如果你只是想忽略未映射的属性,你会做这样的事情:

ObjectMapper om = new ObjectMapper();
om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

但我猜想您希望对未知属性启用一些处理,但同时又将其隐藏在 class 的实际逻辑之外。

在那种情况下,您可以只使用继承而不是 Map 创建一个使用 @JsonAnySetter 注释的方法,例如:

public class UnmappedPropertyHandler {
    @JsonAnySetter
    private void handleUnmapped(String name, String value) {
        // do what you need
    }
}

public class ImportantInterfaceObject extends UnmappedPropertyHandler {
    // ... any actually mapped stuff
}

你也可以声明接口,但是如果Java8你就不能隐藏方法:

interface IUnmappedPropertyHandler {
    @JsonAnySetter
    default void handleUnmapped(String name, String value) {
    }
}

对于 Java11 是可能的,例如:

interface IUnmappedPropertyHandler {
    @JsonAnySetter
    private void handleUnmapped(String name, String value) {
    }
}