-
-
Notifications
You must be signed in to change notification settings - Fork 221
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
XmlMapper
/UntypedObjectDeserializer
swallows duplicated elements in XML documents
#205
Comments
…bject deser Signed-off-by: joaovarandas <[email protected]>
The new test 'testDuplicatedElementsSwallowing' in class 'XmlParserTest' ensures it is working as proposed. Let me know if you want me to pull this. |
I don't think this should be the default behavior, but I would be fine with a feature that allows doing this. One question here is regarding how it should be enabled; at least two possibilities:
Of these I would otherwise favor (2) since it's easier to expand, but one problem is that this feature can not be changed on per-call basis and as such should not be a (format-specific) Alternatively perhaps it would be better to add option (3); add So if you can do a PR for feature itself (with simple setter, for now), and I can retrofit |
The problem with adding as a "optional" feature (or setter) is that "unaware" developers could lose data deserialized from XML. That's what happened to me: - Users found out the bug weeks after it has been deployed to production, since during the tests there were no repeated elements. Anyway, sure I can do that. And it fits my use case as well. |
Another option would be to explicitly fail on any attempt to bind to "untyped" ( In the end I do not think there are good options: ideally XML is not being mapped to either |
Yeah... I agree with you, but: I'm currently building a facade for the Apache Components/HTTPClient, and invoking SOAP services... Then I just "transform" the return object to a simple Map/List, and invoke JavaScript code (using Nashorn). In that use case, it doesn't matter if the object is an Array or a Map since I access them using simple JavaScript bindings like: data["attribute-key"] or data[0] for an array ... Probably for Scala or other languages inside JVM it would be the same. I think failing is good too, to fail when there are duplicated elements in a default UntypedObject deser ...
|
@cowtowncoder how could I "deregister" a Module or the deserializer? See the code below: public XmlMapper setUseXmlUntypedObjectDeserModule(boolean state) {
if (state == true) {
Module xmlUntypedObjectDeserModule = new SimpleModule().addDeserializer(Object.class, new XmlUntypedObjectDeserializer());
registerModule(xmlUntypedObjectDeserModule);
} else {
// is there anyway to rollback the state?
}
return this;
} |
Signed-off-by: joaovarandas <[email protected]>
There is no way to deregister a module, since registration really is just a callback to get a chance to register other things. Further, there is no metadata on what registered any given handler (no back-references to module). So answer is you can not. You can just register more handlers. So question would rather become "what are you trying to do". It is possible to add suitable |
@joaovarandas Thank you, your gist solution saved my day. |
@joaovarandas Saved me, too. Thanks. |
@joaovarandas thanks, your gist solution works perfect. |
Thanks @joaovarandas for your gist |
Thanks @joaovarandas for the solution in gist |
Thanks @joaovarandas for the gist. Worked perfectly. |
I linked this gem to a relevant StackOverflow post. Thanks @joaovarandas for the report and the temporary fix! |
@cowtowncoder, could you please clarify whether this issue has been solved? Using version Thank you! |
@Musikolo it hasn't, and I don't see a way to handle it via Untyped object deserialization. Jackson XML module does not offer general-purpose node approach to XML -- problem is that XML simply has no native difference that would allow separating Arrays (lists) from Objects (maps), and I really really dislike heuristics that try to separate single-value from multiple-values, as this has proven not to be reliable or stable handling for anything. |
Excuse my probably naive question, but why can't we simply use a MultiMap instead of a Map and be good? BTW: The problem with the approach suggested in this issue is that it does not work if you also need to parse the attributes of the keys / tags with the identical names. |
@sschuberth Because "untyped" databinding is defined as using basic One possibility, I think, could be to make |
Absolute life saver! In order to throw my 5 cents on the topic, for me it was crucial to readValue to Object.class instead of TypeReference of Map<String, Object>. Thanks for the workaround provided! |
Is there a workaround for the (XML) JsonNode way as well? |
@cowtowncoder Is this (Handling duplicate elements natively) targeted for 3.0? |
I hope it can be addressed, although I do not really have solid plans. But if there was, I think it'd be one https://github.com/FasterXML/jackson-future-ideas/wiki/JSTEP with a new JSTEP id, description of basic idea. I wish I had some concrete ideas, as I agree with everyone that availability of a tree model is a HUGE win, and that with XML there has to be a way to indicate element sequences, element/attribute distinction. But still isolating it from some of complexities of XML, while keeping model interoperable with other representations. I added tentative placeholder (looks like it'd be `JSTEP-6') on page linked-to above. |
One update: created FasterXML/jackson-databind#2732 to help with |
XmlMapper
/UntypedObjectDeserializer
swallows duplicated elements in XML documents
I ended up implementing suggestion, so that repeated elements result in automatic "upgrade" into Will be in 2.12(.0). |
…2733) # Conflicts: # release-notes/VERSION-2.x
@cowtowncoder does 2.12 release in a few days? |
@taojoe not quite that fast: I am hoping to get the first release candidate (rc1) out within a week, and then bit of time is needed for testing. So earliest I think would be in maybe 4 weeks. |
@cowtowncoder rc1 is ok for me. Thanks a lot. ' repeated elements result in automatic "upgrade" into List' is the key part in my project. It'll save a lot of time. |
@cowtowncoder when will rc1 release ? |
Missed doing it last weekend, now hoping to have time over upcoming weekend, in 4-5 days. |
@cowtowncoder thanks |
I added a ticket to improve handling of repeated elements, see [https://github.com//issues/495] For those with Perl background: current solution is similar to XML::Simple forceArray = true, the addition will follow the forceArray = [ tag1, tag2, …] approach. For parsing in Perl, it was a life saver. |
Hello guys.
I think I have already seen this issue around, but, for UntypedObjectDeserializer the solution maybe a bit different.
Entity
Code
Output
Problem
Duplicated elements in the entity get swallowed by current UntypedObjectDeserializer implementation.
I can't use Typed Objects. In my use case, I don't have any typed objects, because I don't know how objects are sent to me.
Possible Solution
While creating the Map for the data, check if there are duplicated keys, and start an Array, with this approach, the output would be:
How to Reproduce
Gist
Artifacts:
Version:
Conclusion
The gist implements the solution using an extended version of the UntypedObjectDeserializer.
If not the default behavior, what about creating a new DeserializationFeature to enable this(default or not)?
Should you guys like/aprove this solution, I can always fork the project and submit a pull request with the full solution as a feature or default behavior.
Thanks!
Jp
The text was updated successfully, but these errors were encountered: