Jackson xml module: deserializing immutable type with a @JacksonXmlText property

Viewed 3953

I want to serialize an immutable type both as json and as xml:

The serialized JSON is like:

{
    "text" : "... the text..."
}

and the serialized xml is like:

 <asText>_text_</asText>

(note that the text is the xml's element text)

The java object is like:

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

beware that the _text property is final (so the object is immutable) and it's annotated with @JacksonXmlText in order to be serialized as the xml element's text

Being the object immutable, a constructor from the text is needed and the constructor's argument must be annotated with @JsonProperty

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

When serializing / deserializing to/from JSON everything works fine ... the problem arises when serializing / deserializing to/from 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());

The exception is:

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

It seems that the xml module needs the object's constructor to be annotated like:

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

BUT this does NOT even works:

    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)

The annotation @JsonProperty("text") at the constructor's argument is needed to deserialize from JSON

... how can i make this to work

3 Answers
Related