• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • Liutauras Vilda
  • Jeanne Boyarsky
  • paul wheaton
Sheriffs:
  • Ron McLeod
  • Devaka Cooray
  • Henry Wong
Saloon Keepers:
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
  • Tim Moores
  • Mikalai Zaikin
Bartenders:
  • Frits Walraven

Error when trying to deserialize XML into object

 
Ranch Hand
Posts: 105
1
Eclipse IDE MySQL Database Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi guys,

I've been trying to solve a deserialization problem without success for a few hours now.

I obtain an XML from an API call, and this is what needs to be deserialized into a Java object. For so, I use Jackson:



This is my class Conversion whose constructor takes a String as a parameter, the xml itself that needs to be deserialized:



Here we have the class that needs to be used for deserialization:



This is a sample of the XML I receive from the API call:



Lastly, the error message I've been getting:

Error while converting from XML to Object: Unrecognized field "Data" (class com.mpsilvestri.model.ApiResponse), not marked as ignorable (3 known properties: "data", "messages", "message"])
at [Source: (StringReader); line: 3, column: 15] (through reference chain: com.mpsilvestri.model.ApiResponse["Data"])


For a long time along my tests, only "data" was mentioned as a known property.

Would you have any ideas of what the problem could be so that I could proceed with my deserialization process?

Thank you in advance!
 
Saloon Keeper
Posts: 10930
87
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Mostly new stuff to me but I'll take a stab at it.

Messages (plural) is a class to encapsulate a collection of Message objects. So far, so good.

Data should be using the Messages class and not attempting to define it's own "messages" collection.
 
Marcos Silvestri
Ranch Hand
Posts: 105
1
Eclipse IDE MySQL Database Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Carey Brown wrote:Mostly new stuff to me but I'll take a stab at it.

Messages (plural) is a class to encapsulate a collection of Message objects. So far, so good.

Data should be using the Messages class and not attempting to define it's own "messages" collection.



Hi Carey, thanks for joining in!

I did these changes:



I started using the Messages list as you suggested, but the error message remained the same:

Error while converting from XML to Object: Unrecognized field "Data" (class com.mpsilvestri.model.ApiResponse), not marked as ignorable (3 known properties: "data", "messages", "message"])
at [Source: (StringReader); line: 3, column: 15] (through reference chain: com.mpsilvestri.model.ApiResponse["Data"])


Thanks!
 
Saloon Keeper
Posts: 15731
368
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
By default, Jackson maps XML elements to JavaBean properties with the same name.

A getter called "getData" would be associated with a JavaBean propery called "data". But that's not what your XML element is called. Your XML element is called "Data".

To deserialize XML elements to properties that have a different name, you need to use annotations to override the default mapping.
 
Stephan van Hulst
Saloon Keeper
Posts: 15731
368
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This should work:

I strongly recommend you to use the JAXB API instead though, and just use Jackson as an implementation provider.
 
Saloon Keeper
Posts: 28321
210
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:I strongly recommend you to use the JAXB API instead though, and just use Jackson as an implementation provider.



Another alternative is to use the Apache Digester. It is specifically designed to convert XML into a graph of Java objects and is widely used in products like the Tomcat webapp server, which digests not only the Tomcat server config file into a graph of JavaBeans, but also deals with digesting webapp deployment descriptors (Context.xml, /WEB-INF/web.xml).
 
Marcos Silvestri
Ranch Hand
Posts: 105
1
Eclipse IDE MySQL Database Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:This should work:

I strongly recommend you to use the JAXB API instead though, and just use Jackson as an implementation provider.



Hi Stephan,

You definetly helped, I used your idea and managed to walk one step more. However, at the next step, I'm stuck again because I'm running against a visibility problem of the data since the other classes are not public and cannot be in the same Java file.

To demonstrate the issue, look at an attempt to print the data:



This is what I obtain:



I tried using inner classes too, like

- ApiResponse
 - Data
   - Messages
     - Message

but that returned the error message:

Error while converting from XML to Object: Cannot construct instance of `com.mpsilvestri.model.ApiResponse$Data$Messages`: non-static inner classes like this can only by instantiated using default, no-argument constructor
at [Source: (StringReader); line: 3, column: 5] (through reference chain: com.mpsilvestri.model.ApiResponse["Data"])


Would you have any suggestions to me so that I can fetch the data already present after the successful deserialization?

Thank you!
 
Marcos Silvestri
Ranch Hand
Posts: 105
1
Eclipse IDE MySQL Database Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Tim Holloway wrote:

Stephan van Hulst wrote:I strongly recommend you to use the JAXB API instead though, and just use Jackson as an implementation provider.



Another alternative is to use the Apache Digester. It is specifically designed to convert XML into a graph of Java objects and is widely used in products like the Tomcat webapp server, which digests not only the Tomcat server config file into a graph of JavaBeans, but also deals with digesting webapp deployment descriptors (Context.xml, /WEB-INF/web.xml).



Hi Tim,

I've never heard of it before, but as per your description, it is worth having a look if my current options are not enough.

Thanks!
 
Tim Holloway
Saloon Keeper
Posts: 28321
210
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I highly recommend it for anything that needs to construct Java objects from XML, as it makes things much simpler. The basic docs with examples can be found here: https://commons.apache.org/proper/commons-digester/guide/core.html

Just for info, in addition to the basic SAX parser, there's also STaX. SAX basically feeds what it reads to listeners and the listeners have to extract the data they are interested in and build any objects that you want to produce and it's the base reader for both STaX and the Digester. The difference between SAX and STaX is that STaX essentially inverts the parse. Instead of simply listening to the XML stream and pulling out data, you tell STaX what you want retrieved and it only passes on those items.

For completeness, there's also XML Documents, which can invoke SAX to populate themselves, but they have theit own rather complex structure which makes them more suitable for modifications of XML than simply producing objects from XML. Plus the entire Document lives in RAM, so large Documents can be very nenory-hungry.
 
Marcos Silvestri
Ranch Hand
Posts: 105
1
Eclipse IDE MySQL Database Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi everyone,

I've managed to resolve my problems with JDOM, with this example (https://www.tutorialspoint.com/java_xml/java_jdom_parse_document.htm)

Actually, I have just solved this, accomplished 5 minutes ago:

 
Stephan van Hulst
Saloon Keeper
Posts: 15731
368
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Marcos Silvestri wrote:I've managed to resolve my problems with JDOM


I'm glad you got it to work. It's just a pity that you ditched a high level, strongly typed API for a low level, weakly typed API. Your old approach was more elegant and robust.

Marcos Silvestri wrote:Would you have any suggestions to me so that I can fetch the data already present after the successful deserialization?


Literally just replace all the contents of your ApiResponse class with the code I posted. After deserializing it using XmlMapper you can just do this:
 
Marcos Silvestri
Ranch Hand
Posts: 105
1
Eclipse IDE MySQL Database Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:

Marcos Silvestri wrote:I've managed to resolve my problems with JDOM


I'm glad you got it to work. It's just a pity that you ditched a high level, strongly typed API for a low level, weakly typed API. Your old approach was more elegant and robust.

Marcos Silvestri wrote:Would you have any suggestions to me so that I can fetch the data already present after the successful deserialization?


Literally just replace all the contents of your ApiResponse class with the code I posted. After deserializing it using XmlMapper you can just do this:



Hi Stephan,

If you knew how much I'm running out of time, I think you could comprehend it... if your answer had come before, I'd certainly go for it.

If what I'm attempting to do works down the line, I'll be coding lots of similar tasks in the near future, with a variety of XML responses from API calls, so I'll still have the change to try what you suggested, I didn't delete the class, neither will this post be erased

Thank you very much! Regards from Brazil!
 
Attractive, successful people love this tiny ad:
Gift giving made easy with the permaculture playing cards
https://coderanch.com/t/777758/Gift-giving-easy-permaculture-playing
reply
    Bookmark Topic Watch Topic
  • New Topic