Error serializing and deserializing json using polymorphism in java - java

I'm trying to manage different value structure using polimorphism. The next example contains 2 jsons that should be deserialized into the same parent object
{
"maximum": {
"type": "type1",
"value": {
"USD": 1000000,
"GBP": 500000
}
}
}
{
"maximum": {
"type": "type2",
"linkedTo": "linked to item",
"value": 2
}
}
I have defined the next classes to manage that:
#JsonInclude (Include.NON_EMPTY)
#JsonDeserialize (builder = Parent.Builder.class)
public class Parent {
private ParentType maximum;
private Parent(Builder builder) {
this.maximum = builder.maximum;
}
public static Builder builder() { return new Builder(); }
public ParentType getMaximum() {
return maximum;
}
public static class Builder {
private ParentType maximum;
public Builder withMaximum(final ParentType maximum) {
this.maximum = maximum;
return this;
}
public Parent build() {
return new Parent(this);
}
}
}
#JsonInclude (Include.NON_EMPTY)
#JsonDeserialize (builder = ParentType.Builder.class)
public class ParentType {
private String type;
private String linkedTo;
private ParentTypeValue value;
private ParentType(Builder builder) {
this.type = builder.type;
this.linkedTo = builder.linkedTo;
this.value = builder.value;
}
public static Builder builder() { return new Builder(); }
public String getType() {
return type;
}
public String getLinkedTo() {
return linkedTo;
}
public ParentTypeValue getValue() {
return value;
}
public static class Builder {
private String type;
private String linkedTo;
private ParentTypeValue value;
public Builder withType(final String type) {
this.type = type;
return this;
}
public Builder withLinkedTo(final String linkedTo) {
this.linkedTo = linkedTo;
return this;
}
public Builder withValue(final ParentTypeValue value) {
this.value = value;
return this;
}
public ParentType build() {
return new ParentType(this);
}
}
}
And finally I tried the polymorphism of Value with the next structure:
#JsonSubTypes ({
#JsonSubTypes.Type(value = CurrencyMapValue.class, name = "currencymapType"),
#JsonSubTypes.Type(value = StringValue.class, name = "integerType"),
})
public abstract class ParentTypeValue {
}
#JsonTypeName ("integerType")
public class IntegerValue extends ParentTypeValue {
private int value;
private IntegerValue(Builder builder) {
this.value = builder.value;
}
public static Builder builder() { return new Builder(); }
public int getValue() {
return value;
}
public static class Builder {
private int value;
public Builder withValue(final int value) {
this.value = value;
return this;
}
public IntegerValue build() {
return new IntegerValue(this);
}
}
}
#JsonTypeName ("currencymapType")
public class CurrencyMapValue extends LimitTypeValue {
private Map<Currency, Double> value;
private CurrencyMapValue(Builder builder) {
this.value = builder.value;
}
public static Builder builder() { return new Builder(); }
public Map<Currency, Double> getValue() {
return value;
}
public static class Builder {
private Map<Currency, Double> value;
public Builder withValue(final Map<Currency, Double> value) {
this.value = value;
return this;
}
public CurrencyMapValue build() {
return new CurrencyMapValue(this);
}
}
}
I'm guessing the polymorphic structure is wrong as I'm not able to deserialize and serialize is adding an extra value object inside the wanted value. I mean something like that:
"maximum": {
"type": "amount",
"linkedTo": "linkedTo",
"value": {
**"value": {**
"USD": 5000000,
"GBP": 200000
}
}
}
Does anyone have an idea about what is wrong on that?. I appreciate very much your help!

Try this..
Please note that #JsonSubTypes and #JsonTypeInfo annotations are added inside Maximum class.
You dont need #JsonTypeName annotation in your CurrencyMapValue and IntegerValue classes if you are only de-serializing. Yet I have added them.
public abstract class ParentTypeValue {}
#Getter
#Builder
#JsonDeserialize(builder = CurrencyMapValue.CurrencyMapValueBuilder.class)
#JsonTypeName("type1")
public class CurrencyMapValue extends ParentTypeValue {
private Map<String, Double> value;
#JsonPOJOBuilder(withPrefix="")
public static class CurrencyMapValueBuilder {}
}
#Getter
#Builder
#JsonDeserialize(builder = IntegerValue.IntegerValueBuilder.class)
#JsonTypeName("type2")
public class IntegerValue extends ParentTypeValue {
private int value;
private String linkedTo;
#JsonPOJOBuilder(withPrefix="")
public static class IntegerValueBuilder {}
}
#Getter
#Setter
public class Maximum {
#JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "type")
#JsonSubTypes({
#JsonSubTypes.Type(value = CurrencyMapValue.class, name = "type1"),
#JsonSubTypes.Type(value = IntegerValue.class, name = "type2"),
})
private ParentTypeValue maximum;
}

Related

Serialize/Deserialize a java.io.Serializable object but missing type id property

I try to serialize and deserialize an object DataSourceObject that wraps a Serializable object, but I don't know the type of the wrapped object.
When I deserialize the JSON, I get an exception:
Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.accor.assets.TestSerialization$DataSourceObject` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
at [Source: (String)"{"#class":"com.accor.assets.TestSerialization$DataSourceObject","concreteObject":{"#class":"com.accor.assets.TestSerialization$HotelsListBean","version":"1.0","metaResponse":{"#class":"com.accor.assets.TestSerialization$MetaResponse","returncode":"0","date":"10/28/21 09:39:14 AM"},"hotelsList":{"#class":"com.accor.assets.TestSerialization$HotelsList","hotel":["java.util.ArrayList",[{"#class":"com.accor.assets.TestSerialization$Hotel","name":"My Hotel","code":"H001","nbstars":"4","countryCode":"G"[truncated 8 chars]; line: 1, column: 65]
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67)
at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1764)
at com.fasterxml.jackson.databind.DatabindContext.reportBadDefinition(DatabindContext.java:400)
at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1209)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1415)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:362)
Here is a complete example to reproduce the problem:
public class TestSerialization {
public static void main(String[] args) throws JsonProcessingException {
ObjectMapper objectMapper = objectMapper();
HotelsListBean hotelsListBean = new HotelsListBean();
hotelsListBean.setVersion("1.0");
MetaResponse metaResponse = new MetaResponse();
metaResponse.setReturncode("0");
metaResponse.setDate("10/28/21 09:39:14 AM");
hotelsListBean.setMetaResponse(metaResponse);
HotelsList hotelsList = new HotelsList();
Hotel hotel = new Hotel();
hotel.setCode("H001");
hotel.setName("My Hotel");
hotel.setCountryCode("GB");
hotel.setNbstars("4");
hotelsList.getHotel().add(hotel);
hotelsListBean.setHotelsList(hotelsList);
DataSourceObject<HotelsListBean> dataSourceObject = new DataSourceObject<>(hotelsListBean);
String json = objectMapper.writeValueAsString(dataSourceObject);
System.out.println(json);
Object result = objectMapper.readValue(json, Object.class);
System.out.println(result);
}
private static ObjectMapper objectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(JsonGenerator.Feature.IGNORE_UNKNOWN);
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
objectMapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
objectMapper.activateDefaultTyping(objectMapper.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
// Register support of other new Java 8 datatypes outside of date/time: most notably Optional, OptionalLong, OptionalDouble
objectMapper.registerModule(new Jdk8Module());
// Register support for Java 8 date/time types (specified in JSR-310 specification)
objectMapper.registerModule(new JavaTimeModule());
return objectMapper;
}
public static class DataSourceObject<T extends Serializable> implements Serializable {
private static final long serialVersionUID = -6026669040755678830L;
private final T concreteObject;
public DataSourceObject(final T concreteObject) {
this.concreteObject = concreteObject;
}
public T getConcreteObject() {
return concreteObject;
}
}
public static class HotelsListBean implements Serializable {
private final static long serialVersionUID = 1L;
protected String version;
protected MetaResponse metaResponse;
protected HotelsList hotelsList;
public String getVersion() {
return version;
}
public void setVersion(String value) {
this.version = value;
}
public MetaResponse getMetaResponse() {
return metaResponse;
}
public void setMetaResponse(MetaResponse value) {
this.metaResponse = value;
}
public HotelsList getHotelsList() {
return hotelsList;
}
public void setHotelsList(HotelsList hotelsList) {
this.hotelsList = hotelsList;
}
}
public static class MetaResponse implements Serializable {
private final static long serialVersionUID = 1L;
protected String returncode;
protected String date;
public String getReturncode() {
return returncode;
}
public void setReturncode(String value) {
this.returncode = value;
}
public String getDate() {
return date;
}
public void setDate(String value) {
this.date = value;
}
}
public static class HotelsList implements Serializable {
private final static long serialVersionUID = 1L;
protected List<Hotel> hotel;
public List<Hotel> getHotel() {
if (hotel == null) {
hotel = new ArrayList<Hotel>();
}
return this.hotel;
}
}
public static class Hotel implements Serializable {
private final static long serialVersionUID = 1L;
protected String name;
protected String code;
protected String nbstars;
protected String countryCode;
public String getName() {
return name;
}
public void setName(String value) {
this.name = value;
}
public String getCode() {
return code;
}
public void setCode(String value) {
this.code = value;
}
public String getNbstars() {
return nbstars;
}
public void setNbstars(String value) {
this.nbstars = value;
}
public String getCountryCode() {
return countryCode;
}
public void setCountryCode(String value) {
this.countryCode = value;
}
}
}
I would like to know what is possible to successfully deserialize.
(I tried to add #JsonCreator on the DataSourceObject constructor but I get the same exception)
You need to have a no-args constructor for DataSourceObject. You have two options.
Make concreteObject not final:
public static class DataSourceObject<T extends Serializable> implements Serializable {
private static final long serialVersionUID = -6026669040755678830L;
private T concreteObject;
private DataSourceObject() { }
public DataSourceObject(final T concreteObject) {
this.concreteObject = concreteObject;
}
public T getConcreteObject() {
return concreteObject;
}
}
Keep concreteObject final, but it must be assigned to null in the no-args constructor:
public static class DataSourceObject<T extends Serializable> implements Serializable {
private static final long serialVersionUID = -6026669040755678830L;
private final T concreteObject;
private DataSourceObject() {
concreteObject = null;
}
public DataSourceObject(final T concreteObject) {
this.concreteObject = concreteObject;
}
public T getConcreteObject() {
return concreteObject;
}
}
Either option will work.

what should I do to receive enum data in spring boot http request

Now I have a simple enum called AppName:
package misc.enumn.app;
import lombok.Getter;
import misc.enumn.BaseEnum;
/**
* #author dolphin
*/
#Getter
public enum AppName implements BaseEnum {
CRUISE( 1, "cruise"),
BACK(2, "back"),
;
private Integer key;
private String value;
AppName(Integer key, String value) {
this.key = key;
this.value = value;
}
public void setKey(Integer key) {
this.key = key;
}
public void setValue(String value) {
this.value = value;
}
public static AppName getAppMarkByValue(String value) {
AppName datetimeType = null;
for (AppName type : AppName.values()) {
if (type.name().equals(value)) {
datetimeType = type;
}
}
return datetimeType;
}
public static AppName getAppMarkByKey(Short key) {
AppName datetimeType = null;
for (AppName type : AppName.values()) {
if (type.key.equals(key)) {
datetimeType = type;
}
}
return datetimeType;
}
}
then I define a request object like this:
#Data
#NoArgsConstructor
#JsonIgnoreProperties(ignoreUnknown = true)
public class UserLoginRequest implements Serializable {
#ApiModelProperty(value = "app")
private AppName app;
}
when I passed appId 1 to the server side, the server parsed AppName as BACK, I do not understand why it parsed as the BACK not 'CRUISE'? I have already define the enum parser:
public class IntegerCodeToEnumConverterFactory implements ConverterFactory<Integer, BaseEnum> {
private static final Map<Class, Converter> CONVERTERS = Maps.newHashMap();
#Override
public <T extends BaseEnum> Converter<Integer, T> getConverter(Class<T> targetType) {
Converter<Integer, T> converter = CONVERTERS.get(targetType);
if (converter == null) {
converter = new IntegerToEnumConverter<>(targetType);
CONVERTERS.put(targetType, converter);
}
return converter;
}
}
and add to interceptor config:
#Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverterFactory(new IntegerCodeToEnumConverterFactory());
}
but seem still could not parse the enum, what should I do to make it parse the app correctly? this is the wrong parse(I want 1 parsed as CRUISE and 2 parsed as BACK):
By the way, when I replace the app from enum as Integer, it could parse it correctly(receive value 1). But I think using enum may be better for readable.
public class IntegerToEnumConverter <T extends BaseEnum> implements Converter<Integer, T> {
private Map<Integer, T> enumMap = Maps.newHashMap();
public IntegerToEnumConverter(Class<T> enumType) {
T[] enums = enumType.getEnumConstants();
for (T e : enums) {
enumMap.put(e.getKey(), e);
}
}
#Override
public T convert(Integer source) {
T t = enumMap.get(source);
if (ObjectUtils.isNull(t)) {
throw new IllegalArgumentException("");
}
return t;
}
}
what I am doing only support http get method, if you want to parse enum in http post method. define the code like this:
#JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static AppName resolve(Integer key) {
return mappings.get(key);
}
this is my full code:
#Getter
public enum AppName implements BaseEnum {
CRUISE(1, "cruise"),
BACK(2, "back"),
;
#JsonValue
private Integer key;
private String value;
AppName(Integer key, String value) {
this.key = key;
this.value = value;
}
private static final Map<Integer, AppName> mappings;
static {
Map<Integer, AppName> temp = new HashMap<>();
for (AppName courseType : values()) {
temp.put(courseType.key, courseType);
}
mappings = Collections.unmodifiableMap(temp);
}
#EnumConvertMethod
#JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static AppName resolve(Integer key) {
return mappings.get(key);
}
public void setKey(Integer key) {
this.key = key;
}
public void setValue(String value) {
this.value = value;
}
public static AppName getAppMarkByValue(String value) {
AppName datetimeType = null;
for (AppName type : AppName.values()) {
if (type.name().equals(value)) {
datetimeType = type;
}
}
return datetimeType;
}
public static AppName getAppMarkByKey(Short key) {
AppName datetimeType = null;
for (AppName type : AppName.values()) {
if (type.key.equals(key)) {
datetimeType = type;
}
}
return datetimeType;
}
}

Assigning default empty value ("") in the Gson custom serialization for Date field

I m trying to assign default EMPTY ("") value to Date field using custom serializer.
#JsonAdapter(AddInfoSerializer.class)
public class AddInfo {
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyyMMdd")
protected Date deliveryDate;
protected DeliveryTimeZone deliveryTimeZone;
protected ReturnKit returnKit;
public Date getDeliveryDate() {
return deliveryDate;
}
public void setDeliveryDate(Date value) {
this.deliveryDate = value;
}
public DeliveryTimeZone getDeliveryTimeZone() {
return deliveryTimeZone;
}
public void setDeliveryTimeZone(DeliveryTimeZone value) {
this.deliveryTimeZone = value;
}
public ReturnKit getReturnKit() {
return returnKit;
}
public void setReturnKit(ReturnKit value) {
this.returnKit = value;
}
public enum DeliveryTimeZone {
#SerializedName("00")
OPTIONAL("00"),
#SerializedName("08")
ZONE_00_12("08"),
#SerializedName("12")
ZONE_12_14("12"),
#SerializedName("14")
ZONE_14_16("14"),
#SerializedName("16")
ZONE_16_18("16"),
#SerializedName("18")
ZONE_18_20("18"),
#SerializedName("19")
ZONE_18_21("19"),
#SerializedName("20")
ZONE_19_21("20");
private final String value;
DeliveryTimeZone(String value) {
this.value = value;
}
}
public enum ReturnKit {
#SerializedName("1")
REQUESTED("1"),
#SerializedName("0")
NOT_REQUESTED("0"),
#SerializedName("1")
ACCOMPANIED_BY_DEVICE("1"),
#SerializedName("0")
ALONE("0"),
#SerializedName("0")
NOT_NEEDED("0");
private final String value;
ReturnKit(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
}
public class AddInfoSerializer implements JsonSerializer<AddInfo> {
#Override
public JsonElement serialize(AddInfo addInfo, Type type, JsonSerializationContext context) {
JsonObject object = new JsonObject();
if (addInfo.getDeliveryDate() == null) {
object.addProperty("deliveryDate", EMPTY);
} else {
object.addProperty("deliveryDate", addInfo.getDeliveryDate().toString());
}
object.addProperty("deliveryTimeZone",addInfo.getDeliveryTimeZone().toString());
object.addProperty("returnKit",addInfo.getReturnKit().toString());
return object;
}
}
public class AddInfoIdentification extends AddInfo {
#NotNull
protected IdentificationType identificationType;
public IdentificationType getIdentificationType() {
return identificationType;
}
public void setIdentificationType(IdentificationType value) {
this.identificationType = value;
}
public enum IdentificationType {
#SerializedName("0")
UNNECESSARY("0"),
#SerializedName("1")
NECESSARY("1");
private final String value;
IdentificationType(String value) {
this.value = value;
}
}
}
public abstract class ABCRequest :- code
GsonBuilder builder = new GsonBuilder();
Gson gson = builder
.registerTypeAdapter(AddInfo.class, new AddInfoSerializer())
.create();
try {
this.setRequestBody(gson.toJson(this));
}
I m passing object of AddInfoIdentification in jsp page without setting value to deliveryDate field of parent class AddInfo.
deliveryDate parameter should be included in the Json while serialization and set to "".
Kindly advice.

Cannot deserialize generic class hierarchy using Jackson

I'm receiving, for instance, this JSON from an external vendor (where payload can be variable):
{
"payload": {
"enrolledAt": "2018-11-05T00:00:00-05:00",
"userId": "99c7ff5c-2c4e-423f-abeb-2e5f3709a42a"
},
"requestId": "80517bb8-2a95-4f15-9a73-fcf3752a1147",
"eventType": "event.success",
"createdAt": "2018-11-05T16:55:13.762-05:00"
}
I'm trying to model these using this class:
public final class Notification<T extends AbstractModel> {
#JsonProperty("requestId")
private String requestId;
#JsonProperty("eventType")
private String eventType;
#JsonProperty("createdAt")
private ZonedDateTime createdAt;
private T payload;
#JsonCreator
public Notification(#JsonProperty("payload") T payload) {
requestId = UUID.randomUUID().toString();
eventType = payload.getType();
createdAt = ZonedDateTime.now();
this.payload = payload;
}
// getters
}
...and then having these possible (generic) types:
public abstract class AbstractModel {
private String userId;
private Type type;
#JsonCreator
AbstractModel(#JsonProperty("companyUserId") String userId, #JsonProperty("type") Type type) {
this.userId = userId;
this.type = type;
}
// getters
public enum Type {
CANCEL("event.cancel"),
SUCCESS("event.success");
private final String value;
Type(String value) {
this.value = value;
}
public String getValue() { return value; }
}
}
public final class Success extends AbstractModel {
private ZonedDateTime enrolledAt;
#JsonCreator
public Success(String userId, #JsonProperty("enrolledAt") ZonedDateTime enrolledAt) {
super(userId, Type.SUCCESS);
this.enrolledAt = enrolledAt;
}
// getters
}
public final class Cancel extends AbstractModel {
private ZonedDateTime cancelledAt;
private String reason;
#JsonCreator
public Cancel(String userId, #JsonProperty("cancelledAt") ZonedDateTime cancelledAt,
#JsonProperty("reason") String reason) {
super(userId, Type.CANCEL);
this.cancelledAt = cancelledAt;
this.reason = reason;
}
// getters
}
The application is based on Spring Boot, so I'm deserializing the JSON like:
#Component
public final class NotificationMapper {
private ObjectMapper mapper;
public NotificationMapper(final ObjectMapper mapper) {
this.mapper = mapper;
}
public Optional<Notification<? extends AbstractModel>> deserializeFrom(final String thiz) {
try {
return Optional.of(mapper.readValue(thiz, new NotificationTypeReference()));
} catch (final Exception e) { /* log errors here */ }
return Optional.empty();
}
private static final class NotificationTypeReference extends TypeReference<Notification<? extends AbstractModel>> { }
}
...but eventually since I'm posting this right here, Jackson doesn't like any of that so far. I've tried several things like: JsonTypeInfo and JsonSubTypes, but I can't change the JSON input.
Anyone? Any clue(s)?
We ended up adding another key/value pair in the JSON – the contract was indeed modified a little bit to accommodate that "private" key/value pair.
In any case, if somebody runs into the same issue, this is the solution for the approach:
...
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
#JsonIgnoreProperties("_type")
#JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "_type")
#JsonSubTypes({
#JsonSubTypes.Type(value = Cancel.class, name = "_type"),
#JsonSubTypes.Type(value = Fail.class, name = "_type"),
#JsonSubTypes.Type(value = Success.class, name = "_type"),
})
public abstract class AbstractModel {
private String userId;
private Type type;
AbstractModel() { }
AbstractModel(final String userId, final Type type) {
this.userId = userId;
this.type = type;
}
// getters, toString, etc.
public enum Type {
CANCEL("event.cancelled"),
FAIL("event.failed"),
SUCCESS("event.success");
private final String value;
Type(String value) {
this.value = value;
}
public String getValue() { return value; }
}
}

How to make a Hirarchical Json Structure with java program

I am working on a generation JSON. The desired result is:
{
"nodes": [
{
"name": "Jeet123",
"type": 1,
"slug": "",
"entity": "company"
}
],
"links": [
{
"source": 0,
"target": 1,
"value": 1,
"distance": 5
}
]
}
This JSON i have to make. I am Writing this java code.. But it only shows {}
Entry1:
import java.util.ArrayList;
import java.util.List;
import com.google.gson.Gson;
class Entry1 {
private String name;
private int type;
private String slug;
private String entity;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getSlug() {
return slug;
}
public void setSlug(String slug) {
this.slug = slug;
}
public String getEntity() {
return entity;
}
public void setEntity(String entity) {
this.entity = entity;
}
}
Entry2:
class Entry2 {
private String source;
private String target;
private String value;
private String distance;
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
public String getTarget() {
return target;
}
public void setTarget(String target) {
this.target = target;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getDistance() {
return distance;
}
public void setDistance(String distance) {
this.distance = distance;
}
}
EntryListContainer:
class EntryListContainer {
public List<Entry1> nodes;
public List<Entry2> links;
public void setEntryList1(List<Entry1> entryList1) {
this.nodes = nodes;
}
public List<Entry1> getEntryList1() {
return nodes;
}
public void setEntryList2(List<Entry2> entryList1) {
this.links = links;
}
public List<Entry2> getEntryList2() {
return links;
}
}
LinkJson:
public class LinkJson {
public static void main(String[] args) {
EntryListContainer container = new EntryListContainer();
List<Entry1> entryList1 = new ArrayList<>();
List<Entry2> entryList2 = new ArrayList<>();
Entry1 entry1 = new Entry1();
entry1.setName("Jeet123");
entry1.setType(1);
entry1.setSlug("");
entry1.setEntity("company");
entryList1.add(entry1);
Entry2 entry2 = new Entry2();
entry2.setSource("0");
entry2.setTarget("1");
entry2.setValue("1");
entry2.setDistance("5");
entryList2.add(entry2);
container.setEntryList1(entryList1);
container.setEntryList2(entryList2);
Gson gson = new Gson();
System.out.println(gson.toJson(container));
}
}
Bad copy/paste !
public void setEntryList2(List<Entry2> entryList1) {
this.links = links;
}
public void setEntryList1(List<Entry1> entryList1) {
this.nodes = nodes;
}
You should have this :
public void setEntryList2(List<Entry2> links) {
this.links = links;
}
public void setEntryList1(List<Entry1> nodes) {
this.nodes = nodes;
}
The way JSON is usually parsed to get the properties is to find the property names (nodes and links in your code) and then capitalise the first letter and append the get word onto the front to try and use the getter method. Basically your EntryListContainer doesn't follow the Java Bean Conventions that JSON (and GSON by proxy) relies on.
So it didn't print anything because you had no getter method for getNodes or getLinks, you have getEntryList1 and getEntryList2
I'm pretty sure you EntryListContainer class needs to look like this:
class EntryListContainer {
public List<Node> nodes;
public List<Link> links;
public void setNodes(final List<Node> nodes) {
this.nodes = nodes;
}
public List<Node> getNodes() {
return this.nodes;
}
public void setLinks(final List<Link> links) {
this.links = links;
}
public List<Link> getLinks() {
return this.links;
}
}
Create Constructor for your EntryListContainer class:
class EntryListContainer {
private List<Entry1> nodes;
private List<Entry2> links;
public EntryListContainer(List<Entry1> nodes, List<Entry2> links) {
this.nodes = nodes;
this.links = links;
}
}
And then create the container object this way:
EntryListContainer container = new EntryListContainer(entryList1,entryList2);
And then create the json:
Gson gson = new Gson();
System.out.println(gson.toJson(container));
Edit: Not necessary to use the constructor,
Change the following methods in your EntryListContainer class and it will work:
public void setEntryList1(List<Entry1> entryList1) {
this.nodes = entryList1;
}
public void setEntryList2(List<Entry2> entryList2) {
this.links = entryList2;
}

Categories

Resources