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;
}
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.
I have big chunk of data, that I'd like to make it an object in java (E.g. https://haste.razvancode.com/agiyamuyol.json)
I'm running this code:
ObjectMapper mapper = new ObjectMapper();
File f = new File("example.json");
if (!f.exists()) f.createNewFile();
Board board = mapper.readValue(f, Board.class);
System.out.println(board.getName());
and I get this error:
Exception in thread "main" com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "isTemplate" (class com.razvancode.discordbot.Utils.Board$Prefs), not marked as ignorable (21 known properties: "calendarFeedEnabled", "voting", "backgroundBottomColor", "cardAging", "backgroundImage", "background", "canBePrivate", "canBeOrg", "comments", "permissionLevel", "selfJoin", "canInvite", "invitations", "backgroundTopColor", "backgroundBrightness", "hideVotes", "cardCovers", "canBeEnterprise", "backgroundTile", "canBePublic", "backgroundImageScaled"])
at [Source: (File); line: 35, column: 23] (through reference chain: com.razvancode.discordbot.Utils.Board["prefs"]->com.razvancode.discordbot.Utils.Board$Prefs["isTemplate"])
at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:61)
at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:823)
at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:1153)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1589)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1567)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:258)
at com.fasterxml.jackson.databind.deser.impl.InnerClassProperty.deserializeAndSet(InnerClassProperty.java:90)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:288)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2902)
at com.razvancode.discordbot.Test.<init>(Test.java:28)
at com.razvancode.discordbot.Test.main(Test.java:34)
Process finished with exit code 1
I'm 100% sure that is from my Board class, but I'm working for hours now and I still can't get it to work.
Boardclass:
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import java.util.ArrayList;
#NoArgsConstructor
#AllArgsConstructor
public class Board {
#Getter
private Object descData, pinned, datePluginDisable, idBoardSource, limits, templateGallery, ixUpdate, idEnterprise, idMemberCreator;
#Getter
private String shortUrl, dateLastActivity, shortLink, creationMethod, idOrganization, dateLastView, id, url, name, desc;
#Getter
private boolean subscribed, starred, enterpriseOwned, closed;
#Getter
private ArrayList<Memberships> memberships;
#Getter
private ArrayList<String> idTags, powerUps, premiumFeatures;
#Getter
private LabelNames labelNames;
#Getter
private Prefs prefs;
#NoArgsConstructor
#AllArgsConstructor
public static class LabelNames {
#Getter
private String orange, red, sky, pink, green, blue, lime, yellow, black, purple;
}
#NoArgsConstructor
#AllArgsConstructor
public static class Prefs {
#Getter
private String backgroundBrightness, comments, backgroundTopColor, backgroundImage, backgroundBottomColor, voting, permissionLevel, cardAging, invitations, background;
#Getter
private boolean canBeEnterprise, hideVotes, canBeOrg, calendarFeedEnabled, backgroundTile, canBePublic, canBePrivate, canInvite, isTemplate, cardCovers, selfJoin;
#Getter
private ArrayList<BackgroundImageScaled> backgroundImageScaled;
}
#NoArgsConstructor
#AllArgsConstructor
public static class BackgroundImageScaled {
#Getter
private String url;
#Getter
private Long width, height;
}
#NoArgsConstructor
#AllArgsConstructor
public static class Memberships {
#Getter
private String idMember, id, memberType;
#Getter
private boolean unconfirmed, deactivated;
}
}
If you have any ideas on how can I fix it, or where I was wrong please tell me.
It might be related to this answer. You might need to stop lombok from generating the getter as isTemplate() rather than isIsTemplate(), given that jackson will assume the boolean field in the data is called template.
I have a class for all static members. The number of static members is more than 10 (which may increase with time).
I am using lombok and I want to generate Getters/Setters for all static members using single #Getter and #Setter annotations on class as we do for non-static members.
I know that
You can also put a #Getter and/or #Setter annotation on a class. In
that case, it's as if you annotate all the non-static fields in that
class with the annotation.
I also know that
We can annotate static fields individually using #Getter #Setter to generate Getters/Setters for static fields.
But this looks ugly and I want to make my class look as clean as possible.
Is there any way I can configure / Override #Getter and #Setter annotation so that I can annotate the class and it generate Getters and Setters for all members including static and non-static members, after all, what do those methods do is return the mentioned variable.
To be more precise, I want the following code snippet to generate Getters and Setters for all class variables-
#Getter
#Setter
public class myClass {
private static String d;
private static SomePojo c;
private String a;
private Integer b;
private SomeClass d;
}
Add #Getter to the static member itself and it should work.
#Getter
private static final String DEFAULT_VAL = "TEST";
For static fields you have to add #Getter to the specific field:
#Getter
#Setter
public class Task {
#Getter
private static int numberOfTasks;
#Getter
private static int taskId;
private String taskName;
private Integer executionTime;
}
I was setting the value of recordId from the child classes using the default constructor and was not using lombok #Builder initially. Eventually i decided to use the Builder here, but the problem now is lombok Builder overrides my default constructor internally hence the value is never set.
How can I put any hook too make lombok #Builder use my default constructor?
Parent class:
#Getter
#Setter
public abstract class Record {
private String recordId;
}
Child class:
#Getter
#Setter
#Builder
#ToString
#AllArgsConstructor
public class SRecord extends Record {
private static final String RECORD_ID = "REC001";
private String street;
private String city;
public SRecord() {
setRecordId(RECORD_ID); //value of recordId being set
}
}
Lombok's #Builder simply does not use the default constructor. It passes its values to an all-args constructor so that this constructor can fill the new instance with these values. #Builder does not use setters or direct access to the fields to do so. So your default constructor is simply ignored by #Builder.
What you can do is write your own all-args constructor. In it, you set your value for recordId and assign the rest of the fields from the parameters.
I think you should create a constructor in your base class:
#Getter
#Setter
public abstract class Record {
private String recordId;
public Record(String recordId) {
this.recordId = recordId;
}
}
Then use it in the constructor of the inherited class:
#Getter
#Setter
#Builder
public class SRecord extends Record {
private static final String RECORD_ID = "REC001";
private String street;
private String city;
public SRecord(String street, String city) {
super(RECORD_ID);
this.street = street;
this.city = city;
}
}
P.S. If you want to use Lombok Builder with inheritance you can use this technique.