Open SimonCockx opened 2 weeks ago
I am not 100% sure if this is doable or not: but I don't thing @JsonUnwrapped
will work to achieve that.
On figuring out working mapping: the usual way of figuring out compatible structure between Java types and XML output is to try to serialize POJOs in question to create compatible structure.
But... yeah. This is probably not possible currently: your attempt makes sense from user perspective, but I don't think it is possible with XML module handling as is.
On the serialization side, I did manage to get something working.
The problem is that IndexedListSerializer#unwrappingSerializer
returns itself, which makes sense for JSON, but could be better for XML. I replaced this in the BeanSerializerFactory#buildIndexedListSerializer
with a custom UnwrappableIndexedListSerializer
which is exactly the same as IndexedListSerializer
except that it returns something else as unwrappingSerializer
. I then let it return my own UnwrappingIndexedListSerializer
, which unwraps all of the items inside a list.
On the deserialization side however, things seem worse. If I look in the code, it seems Jackson does not support deserializing multiple fields with the same name based on order. In the simpler case where no lists are involved, it already seems to fail, e.g.,
@Test
public void test() throws JsonProcessingException {
ObjectMapper mapper = new XmlMapper();
Document deserialised = mapper.readValue("<document><a>A1</a><b>B1</b><a>A2</a><b>B2</b></document>", Document.class);
// Both `myABPair1` and `myABPair2` are assigned to the second pair... `<a>A2</a><b>B2</b>`
}
public static class Document {
private ABPair myABPair1 = null;
private ABPair myABPair2 = null;
@JsonUnwrapped
public ABPair getMyABPair1() {
return myABPair1;
}
public Document setMyABPair1(ABPair pair) {
myABPair1 = pair;
return this;
}
@JsonUnwrapped
public ABPair getMyABPair2() {
return myABPair2;
}
public Document setMyABPair2(ABPair pair) {
myABPair2 = pair;
return this;
}
}
I'm starting to wonder: is support for order-dependent deserialisation something I can customize (even though it might be hard -- I'm adventurous :)), or does this just go too deep into the Jackson stack? Any advice?
So, yes, I can see why logically supporting @JsonUnwrapped
for List
s on serialization side could make sense for XML. Unfortunately jackson-databind
is supposed to be format-agnostic (although there are some minor deviations to support non-JSON formats, mostly XML, with some capability introspection; and in some cases overrides) so it's not super easy to go about that.
But as you correctly noted, the more difficult part really is deserialization, where JSON's unique names for Objects clashes with translation of XML element sequences (where repetition is common/expected).
As to order-dependant deserialization; ordering is not counted on for "Object" structured things (in JSON, from JSON Objects, in XML, translated element sequences not recognized as Arrays (... from Object model)). Or put another way, deserializers are directly responsible for reading tokens and using them, but there is no customizability exposed by annotations.
So I am not 100% sure how things could proceed here.
@JsonUnwrapped
does not unwrap items inside a list. Below is a minimal example of what I'm trying to achieve.I'm trying to model the following simple XSD scheme in Java.
There is one type
Document
which contains a sequence of alternatinga
andb
elements. E.g., this is a valid XML instance:I tried to represent this in Java using the following classes:
However, the
@JsonUnwrapped
does not seem to work in conjunction withuseWrapping = false
. Unit test reproducing the problem:The actual result is
"<document><abpairs><a>A1</a><b>B1</b></abpairs><abpairs><a>A2</a><b>B2</b></abpairs><abpairs><a>A3</a><b>B3</b></abpairs></document>"
.Is there a way to get this working in Jackson?