如何使用XMLMAPPER的注入



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

我希望能够将 XML置于实例中,并使自动化成员变量由 Spring填充。

有没有办法做到这一点?

ObjectMapper具有SetInjectableValues方法,该方法允许在serialisation/deserialisation期间注册一些我们要使用的外部bean。例如,DeserializationContext类具有FindigntableValue方法,该方法允许以上下文的名义找到先前注册的BEAN。在下面,您可以找到示例,其中显示了一般想法如何做到这一点。首先,声明我们要自动的注射豆:

class InjectBean {
    private int key = ThreadLocalRandom.current().nextInt();
    @Override
    public String toString() {
        return "key => " + key;
    }
}

POJO类,我们要从XML中进行应得的效果,可能看起来像以下内容:

class Pojo {
    private String name;
    private InjectBean dependency;
    // getters, setters, toString
}

现在,我们需要实现将自动启发字段的自定义Deserialiser:

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);
    }
}

deserialiser上方只能用于Pojo类。如果您需要对许多类进行相同的操作,则可以将setDependency方法提取到接口并通过每个POJO实现此接口,您需要以相同的方式处理。在上面的Deserialiser中,而不是铸造到Pojo中,您可以施放到界面。要注册我们的自定义Deserialiser,我将使用BeanDeserializerModifier,但您可以以其他方式执行此操作。例如,如果您已经具有自定义Deserialiser,并且使用@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}

另请参见:

  • 如何将依赖性注入杰克逊自定义Deserializer

相关内容

  • 没有找到相关文章

最新更新