Open dmikurube opened 9 years ago
Usage should already work, as far as recognizing annotation goes.
However.... whether it works with respect to possible reordering needed for use with @JsonCreator
I don't know -- there's a good chance it won't. If it does not, it is likely it will not be possible to make it work, since buffering mechanism would not work well with structural changes needed to support optional wrapping of elements.
So: if this usage does not work (which I assume is the case since you filed the issue :) ), I would suggest only passing non-collection properties via Creator, and using field or setter for collection properties. This will work, and while not optimal, it is unlikely that passing of collection via creator for XML will be supported.
Thank you for the reply. Hmm, sad news... Just adding ElementType.PARAMETER on JacksonXmlElementWrapper didn't work.
Since I don't want to make the instance mutable (non-final), I'm giving it a try to hack jackson-dataformat-xml and jackson-databind. Will send a PR when it succeeds. :)
Right, the problem is not regarding ability to add the annotation there, or even getting it observed by Jackson. Rather, it is because handling of Creator parameters is very different from regular simple properties: since object does not yet exist, parameters typically need to be buffered. And the way XML content is supported requires a few tweaks to handling of token stream, and these are not easy to handle through buffering process.
Any updates here? I am running into a similar issue. Interestingly, the code below worked with Jackson 2.5.4, but it crashes in 2.6.2:
package com.example.test;
import java.util.Arrays;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.dataformat.xml.JacksonXmlModule;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
public class Main {
static class Bean {
private final List<String> values;
@JsonCreator
public Bean(@JacksonXmlProperty(localName="value") List<String> values) {
this.values = values;
}
@JacksonXmlElementWrapper(useWrapping=false)
@JacksonXmlProperty(localName="value")
public List<String> getValues() {
return values;
}
}
public static void main(String[] args) throws Exception {
XmlMapper mapper = new XmlMapper();
JacksonXmlModule module = new JacksonXmlModule();
module.setDefaultUseWrapper(false);
mapper.registerModule(module);
Bean original = new Bean(Arrays.asList("foo", "bar"));
String serialized = mapper.writeValueAsString(original);
System.out.println(serialized);
Bean roundTrip = mapper.readValue(serialized, Bean.class);
System.out.println(roundTrip.getValues());
}
}
Also, if I change the property to not use a custom localName
, it works fine even in 2.6.2:
static class Bean {
private final List<String> values;
@JsonCreator
public Bean(@JacksonXmlProperty(localName="values") List<String> values) {
this.values = values;
}
@JacksonXmlElementWrapper(useWrapping=false)
public List<String> getValues() {
return values;
}
}
As to the original question: no, it is not possible to make @JsonCreator
also contain element wrapper information. There are multiple reasons why this would not work, from conceptual separation (@JsonCreator
is generic, dataformat-agnostic annotation; xml annotations are only defined for xml usage), to differing arity (@JsonCreator
relates to a set of one or more properties, whereas wrapper information is always related to one specific property -- although @JsonCreator
may also be used for "delegating" use case, in which case there is no actual property specified at all).
I would strongly recommend not trying to use combination of List
s and @JsonCreator
with XML module, since I am not confident they can made to work together reliably.
I realize that it is great to be able to use a constructor for creating immutable objects, but sometimes defining a private
setter (or field) just works better (Jackson can access those without problems, but code can not directly call them).
One change wrt annotations in 2.12: @JacksonXmlElementWrapper
is allowed on (constructor) parameters. Will see if I can check whether use itself would work or not.
Looks like this will not work with 2.12 either, despite now being able to specify wrapper annotation. Problem is with matching of property itself.
Interestingly enough it is possible to make deserialization "work" by making both property and wrapper names as labels
(since inner element name is not verified), but this will make serialization wrong (will, as expected, use labels
for both, which is not intention here).
Hello, colleagues. Is there any news? Has anyone succeeded in making @JacksonXmlElementWrapper
with @JsonCreator
work? It's 2.14.1 now, and I don't see any improvements with this. Am I missing something?
@syroeshko I don't think there has been any work on this. It is quite likely that the problem has to do with buffering of XML tokens required by use of Constructor for properties, and there is no clear path on how this can be resolved (although it is now possible for XmlMapper
to provide its token TokenBuffer
implementation).
Do you have a plan to make @JacksonXmlElementWrapper specifiable as a parameter?
I'm wondering to use Jackson-dataformat-XML to deserialize to a immutable class instance, but @JacksonXmlElementWrapper is not available as a @JsonCreator parameter. We do a similar approach for JSON by specifying @JsonProperty on @JsonCreator.
For example: