Jackson xml module: deserializing immutable type with a @JacksonXmlText property
Try adding a public getter for the property. I believe that should fix the deserialization issue.
@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; }}
Actually, it works without adding a getter too, with these versions of 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>
Update 2018
This hack worked in 2.9.0 but it seems to stop working after this commit. It is not clear if there is an easy way to make it work again.
It looks like the main reason for your issue is that you try to use JSON and XML serialization at the same time but with different configurations. Unfortunately XmlMapper
inherits from ObjectMapper
and inherits all the JSON-specific configuration (and you can override it but can not clear it with XML-specific annotations) which is the reason for your conflict. It seems that the simplest way to work this around is to use @JsonAlias
annotation in the constructor. It is a bit hacky but it works. Here is a minimal example (without Lombok) that works for me:
@JsonRootName("asText")public static class AsText { @JsonProperty("text") @JacksonXmlText private final String _text; public AsText(@JsonAlias("") @JsonProperty("text") final String text) { _text = text; } @JsonIgnore public String getText() { return _text; } @Override public String toString() { return "AsText{" + "_text='" + _text + '\'' + '}'; }}
Note that I also added @JsonIgnore
to the getter because else I didn't get XML format you requested (and you can do the same using Lombok's onMethod
as described at onX).
For a simple test:
public static void main(String[] args) throws IOException { // create the object AsText obj = new AsText("123_text_"); // init the mapper //ObjectMapper mapper = new ObjectMapper(); XmlMapper mapper = new XmlMapper(); // write as xml String xml = mapper.writeValueAsString(obj); System.out.println("Serialized Xml\n" + xml); // Read from xml AsText objReadedFromXml = mapper.readValue(xml, AsText.class); System.out.println("Read from Xml: " + objReadedFromXml);}
I get the following output:
Serialized Xml
<asText>123_text_</asText>
Read from Xml: AsText{_text='123_text_'}