英文:
Jackson: How to use a custom deserializer with @JsonAnySetter annotation?
问题
我有几个YAML配置文件,我想将它们反序列化成一个类。文件中的YAML由简单的名称值对组成,没有嵌套。有一些属性将有明确的字段,但我只想将其余的内容放入Map中。
这一切都运行良好,但我还希望通过.add()
反序列化到Map中的属性的所有值都经过自定义反序列化器处理。我尝试在setter值参数和setter方法本身上使用@JsonDeserialize
,但Jackson似乎完全忽略了它。
设置如下:
public class ConfigData {
private Map<String, Object> dynamicConfig = new LinkedHashMap<>();
@JsonAnyGetter
public Map<String, Object> getConfig() {
return dynamicConfig;
}
@JsonAnySetter
public void add(String name, @JsonDeserialize(using = FooDeserializer.class) Object value) {
dynamicConfig.put(name, value);
}
@JsonProperty("some_special_property")
public String setSomeSpecialProperty(String value) {
add("some_special_property", value);
}
}
用于反序列化的代码如下:
public static ConfigData getConfig(URL configResource) throws IOException {
try (InputStream stream = configResource.openStream()) {
ObjectMapper mapper = new YAMLMapper();
return mapper.readValue(new InputStreamReader(stream, StandardCharsets.UTF_8), ConfigData.class);
}
}
英文:
I have several YAML config files I want to deserialize into a class. The YAML in the files consists of simple name value pairs with no nesting. There's a handful of properties that will have explicit fields, but the rest I just want dumped into a Map.
This all works fine, but I also want all the values of the properties that get deserialized into the Map through .add()
to be run through a custom deserializer. I've tried using @JsonDeserialize
on the setter value parameter and the setter method itself but Jackson seems to ignore it altogether.
Here's how it's set up:
public class ConfigData {
private Map<String, Object> dynamicConfig = new LinkedHashMap<>();
@JsonAnyGetter
public Map<String, Object> getConfig() {
return dynamicConfig;
}
@JsonAnySetter
public void add(String name, @JsonDeserialize(using = FooDeserializer.class) Object value) {
dynamicConfig.put(name, value);
}
@JsonProperty("some_special_property")
public String setSomeSpecialProperty(String value) {
add("some_special_property", value);
}
}
And to deserialize:
public static ConfigData getConfig(URL configResource) throws IOException {
try (InputStream stream = configResource.openStream()) {
ObjectMapper mapper = new YAMLMapper();
return mapper.readValue(new InputStreamReader(stream, StandardCharsets.UTF_8), ConfigData.class);
}
}
答案1
得分: 1
我发现问题是我在@JsonDeserialize
注解的using
属性中指定了反序列化器类。对于这种特定用例,我需要使用contentUsing
属性,该属性用于像Map条目的值字段之类的情况。
这是我的setter现在的样子:
@JsonAnySetter
@JsonDeserialize(contentUsing = FooDeserializer.class)
public void add(String name, Object value) {
dynamicConfig.put(name, value);
}
现在所有的值都将使用FooDeserializer
进行序列化,除了"some_special_property"
,它有自己的setter。
英文:
I discovered the problem was that I was specifying the deserializer class with the using
property of the @JsonDeserialize
annotation. For this specific use case I needed to use the contentUsing
property instead, which is used for things like the value field of a Map entry.
This is what my setter looks like now:
@JsonAnySetter
@JsonDeserialize(contentUsing = FooDeserializer.class)
public void add(String name, Object value) {
dynamicConfig.put(name, value);
}
Now all the values will be serialized using FooDeserializer
, except for "some_special_property"
which has its own setter.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论