gpt4 book ai didi

java - 如何使用XmlMapper反序列化注入(inject)

转载 作者:太空宇宙 更新时间:2023-11-04 09:40:48 26 4
gpt4 key购买 nike

我正在使用 com.fasterxml.jackson.dataformat.xml 中的 XmlMapper。我正在序列化的类有一个未序列化的 Autowired 成员。

我希望能够将 XML 反序列化为实例,并让 Autowiring 的成员变量由 Spring 填充。

有办法做到这一点吗?

最佳答案

ObjectMappersetInjectableValues方法允许注册一些我们想要在序列化/反序列化期间使用的外部bean。例如,DeserializationContext 类有 findInjectableValue允许按名称在上下文中查找先前注册的 bean 的方法。您可以在下面找到示例,其中显示了如何做到这一点的总体思路。首先,声明一个我们想要 Autowiring 的可注入(inject) bean:

class InjectBean {

private int key = ThreadLocalRandom.current().nextInt();

@Override
public String toString() {
return "key => " + key;
}
}
我们想要从 XML 反序列化的

POJO 类可能如下所示:

class Pojo {

private String name;
private InjectBean dependency;

// getters, setters, toString
}

现在,我们需要实现自定义反序列化器,它将注入(inject) Autowiring 字段:

class PojoBeanDeserializer extends BeanDeserializer {

public static final String DEPENDENCY_NAME = "injectBean";

public PojoBeanDeserializer(BeanDeserializerBase src) {
super(src);
}

@Override
public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
Object deserialize = super.deserialize(p, ctxt);
InjectBean injectableValue = findInjectableValue(ctxt);

Pojo pojo = (Pojo) deserialize;
pojo.setDependency(injectableValue);

return deserialize;
}

private InjectBean findInjectableValue(DeserializationContext context) throws JsonMappingException {
return (InjectBean) context.findInjectableValue(DEPENDENCY_NAME, null, null);
}
}

上述反序列化器只能用于Pojo类。如果您需要对许多类执行相同的操作,您可以将 setDependency 方法提取到一个接口(interface),并通过您需要以相同方式处理的每个 POJO 实现该接口(interface)。在上面的反序列化器中,您可以转换为接口(interface),而不是转换为 Pojo。为了注册我们的自定义反序列化器,我将使用 BeanDeserializerModifier,但您可以通过其他方式来实现。例如,如果您已经有自定义反序列化器并且使用 @JsonDeserialize 注释,则不需要这样做。简单的用法如下所示:

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.DeserializationConfig;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.InjectableValues;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.deser.BeanDeserializer;
import com.fasterxml.jackson.databind.deser.BeanDeserializerBase;
import com.fasterxml.jackson.databind.deser.BeanDeserializerModifier;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;

import java.io.File;
import java.io.IOException;
import java.util.concurrent.ThreadLocalRandom;

public class XmlMapperApp {

public static void main(String[] args) throws Exception {
File xmlFile = new File("./resource/test.xml").getAbsoluteFile();

InjectBean injectBean = autowire();
InjectableValues.Std injectableValues = new InjectableValues.Std();
injectableValues.addValue(PojoBeanDeserializer.DEPENDENCY_NAME, injectBean);

SimpleModule injectModule = new SimpleModule();
injectModule.setDeserializerModifier(new InjectBeanDeserializerModifier());

XmlMapper xmlMapper = new XmlMapper();
xmlMapper.registerModule(injectModule);
xmlMapper.setInjectableValues(injectableValues);

Pojo bean = xmlMapper.readValue(xmlFile, Pojo.class);

System.out.println("After deserialization:");
System.out.println(bean);
}

private static InjectBean autowire() {
InjectBean bean = new InjectBean();

System.out.println("Injectable bean from context: " + bean);

return bean;
}
}

class InjectBeanDeserializerModifier extends BeanDeserializerModifier {
@Override
public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config, BeanDescription beanDesc, JsonDeserializer<?> deserializer) {
if (beanDesc.getType().getRawClass() == Pojo.class) {
JsonDeserializer<?> jsonDeserializer = super.modifyDeserializer(config, beanDesc, deserializer);

return new PojoBeanDeserializer((BeanDeserializer) jsonDeserializer);
}

return super.modifyDeserializer(config, beanDesc, deserializer);
}
}

对于以下 XML 有效负载:

<Pojo>
<name>Tom</name>
</Pojo>

打印:

Injectable bean from context: key => 909636975
After deserialization:
Bean{name='Tom', dependency=key => 909636975}

另请参阅:

关于java - 如何使用XmlMapper反序列化注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56015253/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com