Deserializing XML containing list into a POJO - java

My XML looks something like this:
<asset id="35465146">
<TOV artist="" music="0" episodeNumber="">
<credit biography="" />
<credit biography="" />
<credit biography="" />
<credit biography="" />
<castCrew role="Actor" name="John C. Reilly"/>
<castCrew role="Director" name="Keith Scholey"/>
<castCrew role="Director" name="Alastair Fothergill"/>
<castCrew role="Director" name="Adam Chapman"/>
</TOV>
</asset>
My asset POJO looks like this:
public class asset {
#Getter #Setter private String id;
#Getter #Setter private TOV TOV;
}
and the TOV class look like this:
public class TOV {
#Getter #Setter private String episodeNumber;
#Getter #Setter private String music;
#Getter #Setter private String artist;
#Getter #Setter private List<credit> credit;
#Getter #Setter private List<castCrew> castCrew;
}
Now, I run the code and get a null pointer.
When I debug the code I see that the asset object has been created and that the ID field has been extracted from the XML. However, the TOV object is equal to null. Do I require some sort of label to tell Jackson that the TOV java object maps to the XML one? Also, would having credit and castCrew inside a java List work?

In the asset class I was missing
#JacksonXmlProperty(localName = "TOV")
On top of
#Getter #Setter private TOV TOV;
And for the list I needed to add
#JacksonXmlElementWrapper(useWrapping = false)
#JacksonXmlProperty(localName = "castCrew")
Both problems were just related to having to specify which field in java it should be mapped to in the XML

Related

How can I use JAXB to bind mulitple non-unique elements

I'm having this issue with parsing XML using JAXB. Here is a simplified layout of the XML in question:
<message>
<header>
<network>NET</network>
<sendTime>0722</sendTime>
</header>
<generalInformation>
<senderReference>1234</senderReference>
<linkage>
<externalReference>extRef</externalReference>
</linkage>
<linkage>
<internalReference>intRef</internalReference>
</linkage>
<linkage>
<systemReference>sysRef</externalReference>
</linkage>
</generalInformation>
</message>
The problem I'm having is that these references are being sent under the linkage tag which is not unique, and also doesn't have a root like "linkages" which would allow me to easily wrap it in a list in Java, because the generalInformation tag has other tags in it. Here is how I have it set up so far:
#XmlRootElement(name="message")
#NoArgsConstructor
#AllArgsConstructor
#Data
public class Message {
private Header header;
private GeneralInformation generalInformation;
}
#XmlRootElement(name="header")
#NoArgsConstructor
#AllArgsConstructor
#Data
public class Header {
private String network;
private String sendTime;
}
#XmlRootElement(name="generalInformation")
#NoArgsConstructor
#AllArgsConstructor
#Data
public class GeneralInformation {
private String senderReference;
//How to create for linkages??
}
So my question to you is, how can I configure the GeneralInformation class to handle these multiple linkages? I am mostly concerned with unmarshalling from XML to Java at the moment.
Just define it as a List, for example:
private List<Linkage> linkage;
and define the Linkage class to have single String property:
#XmlRootElement(name="linkage")
...
public class Linkage {
private String systemReference;
}
#XmlRootElement(name="generalInformation")
#NoArgsConstructor
#AllArgsConstructor
#Data
public class GeneralInformation {
private String senderReference;
private List<Linkage>;
}
#XmlRootElement(name="linkage")
#NoArgsConstructor
#AllArgsConstructor
#Data
public class Linkage {
private String externalReference;
private String internalReference;
private String systemReference;
}

Can I use a java class inside protobuf file?

I have two java classes, called MyJavaClass and MyAnotherJavaClass.
MyJavaClass :
#Data
#Builder
#AllArgsConstructor
#NoArgsConstructor
public class MyJavaClass implements Serializable {
private Integer id;
private String name;
private MyAnotherJavaClass myAnotherJavaClass;
}
MyAnotherJavaClass:
#Data
#Builder
#AllArgsConstructor
#NoArgsConstructor
public class MyAnotherJavaClass implements Serializable {
private Integer id;
private String someField;
}
Can I have something like this?
message MyClassMessage {
MyJavaClass javaclass = 1;
}
Instead of create a message to use protobuf, since I use the same fields.

How to exclude boolean type value for jackson payload

I have really simple requirement to exclude Boolean type attribute from payload during Jackson serialization. Following is the piece of code that I want to fix that. I want exclude it always irrespective to its value.
#Getter
#Setter
#NoArgsConstructor
#XmlRootElement
public class Order{
#JsonIgnore
private boolean userPresent;
}
Can someone help me on this?
You should explicitly add the Getter for the property you want to ignore and set the #JsonIgnore there:
#Getter
#Setter
#NoArgsConstructor
#XmlRootElement
public class Order{
private boolean userPresent;
#JsonIgnore
public boolean isUserPresent() {
return this.userPresent;
}
}
If you don't have any other properties in the class, you should remove the #Getter annotation because it is redundant now.

Trouble mapping XML to a list of POJOs in Jackson

I need to take XML that looks like something like the following:
<root:ElementName>
<equipment:Equipment>
<eqp:Name>Equipment 1</eqp:Name>
<eqp:Type>A</eqp:Type>
</equipment:Equipment>
<equipment:Equipment>
<eqp:Name>Equipment 2</eqp:Name>
<eqp:Type>B</eqp:Type>
</equipment:Equipment><equipment:Equipment>
<eqp:Name>Equipment 3</eqp:Name>
<eqp:Type>C</eqp:Type>
</equipment:Equipment>
</root:ElementName>
And I want to map that into a list of "Equipment" POJOs. I'm using Jackson XML mapping and Lombok, so basically I've got this split into two classes right now, first the root object which should read in that <root:ElementName> and turn all the <equipment:Equipment> tags into a list of equipment objects:
#JacksonXmlRootElement(localName = "root:ElementName")
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonIgnoreProperties(ignoreUnknown = true)
public class EquipmentMidbCompositeResponse
{
#JsonProperty("equipment")
#JacksonXmlProperty(localName = "equipment:Equipment")
#Getter
#Setter
List<Equipment> equipmentList;
}
And then the Equipment object itself:
#Entity
#Data
#NoArgsConstructor
#EqualsAndHashCode(callSuper = true)
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonIgnoreProperties(ignoreUnknown = true)
public final class Equipment
{
#JsonCreator
public Equipment(String name){
}
#JsonProperty("EquipmentName")
#JacksonXmlProperty(localName = "eqp:Name")
#Setter
#Getter
private String name;
#JsonProperty("EquipmentType")
#JacksonXmlProperty(localName = "eqp:Type")
#Setter
#Getter
private String type;
}
At first I didn't have that constructor with #JsonCreator in the Equipment object and would get a "no String-argument constructor/factory method to deserialize from String value" error, and after some research added the constructor to get around that. With that I get past that error, but the list of Equipment objects that gets returned after mapping have all their fields set to null. What am I missing/doing wrong here when trying to map these XML properties?
(Posted on behalf of the OP).
I figured out the issue, my approach with the #JsonCreator was the incorrect way to go for that error. Turns out all I had to do was an a #JacksonXmlElementWrapper(useWrapping=false) annotation to my list item and everything went through just fine.

Add validation rules to Pojo.name to object extending Pojo?

I have a simple java pojo which i give to my android users:
#XmlRootElement
#AllArgsConstructor
#NoArgsConstructor
#ToString
public class PostAccount {
#Getter
#Setter
private String email;
#Getter
#Setter
private String pass1;
#Getter
#Setter
private String pass2;
}
This pojo is serialized to json and send to my server. On my server i which to use jersey bean validation:
public NumberResult add(#Valid ValidAccount account) {
But because the Account pojo doesn't have any validation annotations validation doesn't do much.
I can create a second pojo with validation annotations and use that on server side:
public class ValidAccount {
#Getter
#Setter
#NotEmpty
#CheckEmail
private String email;
#Getter
#Setter
#NotBlank
private String pass1;
#Getter
#Setter
#NotBlank
private String pass2;
}
Works perfectly.
But when i now add a field at Account pojo i do have to remember to change ValidAccount pojo. No problem, but when you have a lot of pojo's things get complicated to manage.
Is there a better solution?
For example is it possible to extends the Account pojo and in a way add the validation rules? (please i which to continue using annotations, xml gives me the creeps)

Categories