Jackson xml模块:使用@JacksonXmlText属性反序列化不可变类型

fut*_*ics 15 java xml jackson

我想将一个不可变类型序列化为json和xml:

序列化的JSON如下:

{
    "text" : "... the text..."
}
Run Code Online (Sandbox Code Playgroud)

序列化的xml如下:

 <asText>_text_</asText>
Run Code Online (Sandbox Code Playgroud)

(注意文本是xml的元素文本)

java对象如下:

@JsonRootName("asText")
@Accessors(prefix="_")
public static class AsText {

    @JsonProperty("text") @JacksonXmlText
    @Getter private final String _text;

    public AsText(@JsonProperty("text") final String text) {
        _text = text;
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意_text属性是final(因此对象是不可变的)并且它被注释@JacksonXmlText以便被序列化为xml元素的文本

作为对象不可变,需要来自文本的构造函数,并且必须使用构造函数的参数进行注释 @JsonProperty

    public AsText(@JsonProperty("text") final String text) {
        _text = text;
    }
Run Code Online (Sandbox Code Playgroud)

对JSON进行序列化/反序列化时,一切正常......在向/从XML序列化/反序列化时出现问题:

 // create the object
 AsText obj = new AsText("_text_");

 // init the mapper
 XmlMapper mapper = new XmlMapper();

 // write as xml
 String xml = mapper.writeValueAsString(obj);
 log.warn("Serialized Xml\n{}",xml);

 // Read from xml
 log.warn("Read from Xml:");
 AsText objReadedFromXml = mapper.readValue(xml,
                                              AsText.class);
 log.warn("Obj readed from serialized xml: {}",
          objReadedFromXml.getClass().getName());
Run Code Online (Sandbox Code Playgroud)

例外是:

    com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "" (class r01f.types.url.UrlQueryStringParam), not marked as ignorable (2 known properties: "value", "name"])

似乎xml模块需要对对象的构造函数进行注释,如:

    public AsText(@JsonProperty("") final String text) {
        _text = text;
    }
Run Code Online (Sandbox Code Playgroud)

但这甚至不起作用:

    com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `test.types.SerializeAsXmlElementTextTest$AsText` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)

@JsonProperty("text")构造函数参数的注释需要从JSON反序列化

......我怎么能让它发挥作用

Aru*_*lan 5

尝试为该属性添加公共getter.我认为应该解决反序列化问题.

@JsonRootName("asText")
@Accessors(prefix = "_")
public static class AsText {

    @JsonProperty("text")
    @JacksonXmlText
    @Getter
    private final String _text;

    public AsText(@JsonProperty("text") final String text) {
        _text = text;
    }

    public String getText() {
        return _text;
    }
}
Run Code Online (Sandbox Code Playgroud)

实际上,使用这些版本的Lombak和Jackson,它也可以在不添加吸气剂的情况下工作.

<dependencies>
    <dependency>
        <groupId>com.fasterxml.jackson.dataformat</groupId>
        <artifactId>jackson-dataformat-xml</artifactId>
        <version>2.9.0</version>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.16.18</version>
    </dependency>
</dependencies>
Run Code Online (Sandbox Code Playgroud)