Fasterxml - TypeReference construction with generics [duplicate] - java

For json mapping I use the following method:
public static <T> T mapJsonToObject(String json, T dtoClass) throws Exception {
ObjectMapper mapper = new ObjectMapper();
return mapper.readValue(json, new TypeReference<RestResponse<UserDto>>() {
});
}
And UserDto looks like this:
#JsonIgnoreProperties(ignoreUnknown = true)
public class UserDto {
#JsonProperty("items")
private List<User> userList;
public List<User> getUserList() {
return userList;
}
public void setUserList(List<User> userList) {
this.userList = userList;
}
}
I want to improve this method of mapping without being attached to a UserDto class, and replacing it with a generic.
Is it possible? And How?
Thanks.

TypeReference requires you to specify parameters statically, not dynamically, so it does not work if you need to further parameterize types.
What I think you need is JavaType: you can build instances dynamically by using TypeFactory. You get an instance of TypeFactory via ObjectMapper.getTypeFactory(). You can also construct JavaType instances from simple Class as well as TypeReference.

One approach will be to define a Jackson JavaType representing a list of items of type clazz. You still need to have access to the class of the generic parameter at runtime. The usual approach is something like
<T> class XX { XX(Class<T> clazz, ...) ... }
to pass the class of the generic parameter into the generic class at construction.
Upon access to the Class clazz variable you can construct a Jackson JavaType representing, for example, a list of items of class clazz with the following statement.
JavaType itemType = mapper.getTypeFactory().constructCollectionType(List.class, clazz);
I hope it helped. I am using this approach in my own code.

Try this:
import com.fasterxml.jackson.databind.ObjectMapper;
import java.lang.reflect.Array;
import java.util.Arrays;
...
public static <TargetType> List<TargetType> convertToList(String jsonString, Class<TargetType> targetTypeClass) {
List<TargetType> listOfTargetObjects = null;
ObjectMapper objectMapper = new ObjectMapper();
TargetType[] arrayOfTargetType = (TargetType[]) Array.newInstance(targetTypeClass, 0);
try {
listOfTargetObjects = (List<TargetType>) Arrays.asList(objectMapper.readValue(jsonString, arrayOfTargetType.getClass()));
} catch (JsonMappingException jsonMappingException) {
listOfTargetObjects = null;
} catch (JsonProcessingException jsonProcessingException) {
listOfTargetObjects = null;
} catch (Exception exception) {
listOfTargetObjects = null;
}
return listOfTargetObjects;
}
...

This is an example of parsing simple List based generics with Jackson, with a simple Java annotation!
package innovate.tamergroup.lastmiledelivery.loader.otm.models;
import java.util.List;
import javax.annotation.Generated;
import com.fasterxml.jackson.annotation.JsonInclude
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({
"hasMore",
"limit",
"count",
"offset",
"items",
"links"
})
#Generated("jsonschema2pojo")
public class OTMListWrapper<T> {
#JsonProperty("hasMore")
private Boolean hasMore;
#JsonProperty("limit")
private Long limit;
#JsonProperty("count")
private Long count;
#JsonProperty("offset")
private Long offset;
#JsonTypeInfo(use=JsonTypeInfo.Id.NONE, include=JsonTypeInfo.As.PROPERTY, property="items")
private List<T> items = null;
#JsonProperty("links")
private List<OTMLink> links = null;
#JsonProperty("hasMore")
public Boolean getHasMore() {
return hasMore;
}
#JsonProperty("hasMore")
public void setHasMore(Boolean hasMore) {
this.hasMore = hasMore;
}
public OTMListWrapper<T> withHasMore(Boolean hasMore) {
this.hasMore = hasMore;
return this;
}
#JsonProperty("limit")
public Long getLimit() {
return limit;
}
#JsonProperty("limit")
public void setLimit(Long limit) {
this.limit = limit;
}
public OTMListWrapper<T> withLimit(Long limit) {
this.limit = limit;
return this;
}
#JsonProperty("count")
public Long getCount() {
return count;
}
#JsonProperty("count")
public void setCount(Long count) {
this.count = count;
}
public OTMListWrapper<T> withCount(Long count) {
this.count = count;
return this;
}
#JsonProperty("offset")
public Long getOffset() {
return offset;
}
#JsonProperty("offset")
public void setOffset(Long offset) {
this.offset = offset;
}
public OTMListWrapper<T> withOffset(Long offset) {
this.offset = offset;
return this;
}
#JsonProperty("items")
public List<T> getItems() {
return items;
}
#JsonProperty("items")
public void setItems(List<T> items) {
this.items = items;
}
public OTMListWrapper<T> withItems(List<T> items) {
this.items = items;
return this;
}
#JsonProperty("links")
public List<OTMLink> getLinks() {
return links;
}
#JsonProperty("links")
public void setLinks(List<OTMLink> links) {
this.links = links;
}
public OTMListWrapper<T> withLinks(List<OTMLink> links) {
this.links = links;
return this;
}
}

Related

mapstruct wrapper type and generics

I am trying to map JsonNullable<List<ChildRequestTO> to Nullable<List<ChildRequestDO>> (see full code below) with mapstruct 1.4.2.Final and I am facing the following error: error: Nullable<List<ChildRequestDO>> does not have an accessible constructor. If I add a constructor for Nullable like
public Nullable(T value) {
this.value = value;
this.isPresent = true;
}
then I get the following error error: Unmapped target property: "value". Mapping from property "JsonNullable<List<ChildRequestTO>> products" to "Nullable<List<ChildRequestDO>> products".
How do I map complex wrapped types in a generic way?
The following mapping code (part of ChildRequestMapper class and applied in ObjectRequestMapper) solves the problem but I want to solve it in a more generic way:
#Named("mappingHelper")
default Nullable<List<ChildRequestDO>> customMapToDOs(JsonNullable<List<ChildRequestTO>> input) {
if (JsonNullable.undefined().equals(input)) {
return Nullable.undefined();
}
if (input.get() == null) {
return Nullable.of(null);
}
var output= input.get()
.stream()
.map(this::mapToDO)
.collect(Collectors.toList());
return Nullable.of(output);
}
Changing the NullableMapper to the code below does not work/compile because I do not know how to tell mapstruct to look for the appropriate mapper to map from T to X.
public static <T, X> Nullable<X> jsonNullableToNullable(JsonNullable<T> jsonNullable) {
if (jsonNullable.isPresent()) {
return Nullable.of(jsonNullable.get());
}
return Nullable.undefined();
}
Full code:
#Mapper(
unmappedTargetPolicy = ReportingPolicy.ERROR,
uses = {ChildRequestMapper.class, NullableMapper.class}
)
public interface ObjectRequestMapper {
#Mapping(target = "slots", source = "slots", qualifiedByName = "mapToSlotDOs")
ModifyObjectRequestDO mapToDO(ModifyObjectRequestTO input);
}
#Mapper(unmappedTargetPolicy = ReportingPolicy.ERROR)
public interface ChildRequestMapper {
ChildRequestDO mapToDO(ChildRequestTO input);
}
public class NullableMapper {
public static <T> Nullable<T> jsonNullableToNullable(JsonNullable<T> jsonNullable) {
if (jsonNullable.isPresent()) {
return Nullable.of(jsonNullable.get());
}
return Nullable.undefined();
}
}
public class ModifyObjectRequestTO {
private JsonNullable<String> name = JsonNullable.undefined();
private JsonNullable<List<ChildRequestTO>> children = JsonNullable.undefined();
}
public class ModifyObjectRequestDO {
private Nullable<String> name = Nullable.undefined();
private Nullable<List<ChildRequestDO>> children = Nullable.undefined();
}
public class Nullable<T> {
private static final Nullable<?> UNDEFINED = new Nullable<>(null, false);
private final T value;
private final boolean isPresent;
private Nullable(T value, boolean isPresent) {
this.value = value;
this.isPresent = isPresent;
}
public static <T> Nullable<T> undefined() {
#SuppressWarnings("unchecked")
Nullable<T> t = (Nullable<T>) UNDEFINED;
return t;
}
public static <T> Nullable<T> of(T value) {
return new Nullable<T>(value, true);
}
public T get() {
if (!isPresent) {
throw new NoSuchElementException("Value is undefined");
}
return value;
}
public boolean isPresent() {
return isPresent;
}
}

How to make Jackson to inject the Generic Class into a bean?

Lets suppose, that we have a bean like this:
public class Response<T> {
private T data;
private double executionDuration;
private boolean success;
private String version;
//HOW TO Make Jackson to inject this?
private Class<T> dataClass;
public Optional<T> getData() {
return Optional.ofNullable(data);
}
public double getExecutionDuration() {
return executionDuration;
}
public Class<T> getDataClass() {
return dataClass;
}
public String getVersion() {
return version;
}
public boolean isSuccess() {
return success;
}
}
The deserialization happens like this:
objectMapper.readValue(json, new TypeReference<Response<SomeClass>>() {});
Can I somehow make Jackson to inject the class "SomeClass" into my bean? Injecting the type reference itself would be also ok, I think.
If it is undesirable to save class info in json and use #JsonTypeInfo I would suggest to use #JacksonInject:
public class Response<T> {
private T data;
private double executionDuration;
private boolean success;
private String version;
#JacksonInject("dataClass")
private Class<T> dataClass;
public Optional<T> getData() {
return Optional.ofNullable(data);
}
public double getExecutionDuration() {
return executionDuration;
}
public Class<T> getDataClass() {
return dataClass;
}
public String getVersion() {
return version;
}
public boolean isSuccess() {
return success;
}
}
Deserialization would look like:
ObjectMapper mapper = new ObjectMapper();
InjectableValues.Std injectable = new InjectableValues.Std();
injectable.addValue("dataClass", SomeClass.class);
mapper.setInjectableValues(injectable);
final Response<Integer> response = mapper.readValue(json, new TypeReference<Response<SomeClass>>() { });
this worked for me;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
#Getter
#Setter
#NoArgsConstructor
public class Entity<T> {
private T data;
#JsonSerialize(converter = ClassToStringConverter.class)
#JsonDeserialize(converter = StringToClassConverter.class)
private Class<T> dataClass;
}
and
import com.fasterxml.jackson.databind.util.StdConverter;
public class ClassToStringConverter extends StdConverter<Class<?>, String> {
public String convert(Class<?> aClass) {
// class java.lang.Integer
return aClass.toString().split("\\s")[1];
}
}
and
import com.fasterxml.jackson.databind.util.StdConverter;
public class StringToClassConverter extends StdConverter<String, Class<?>> {
public Class<?> convert(String s) {
try {
return Class.forName(s);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
}
Main;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
Entity<Integer> data = new Entity<Integer>();
data.setData(5);
data.setDataClass(Integer.class);
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(data);
Entity<Integer> jsonData = mapper.readValue(json, new TypeReference<Entity<Integer>>() {});
System.out.println(jsonData.getData());
System.out.println(jsonData.getDataClass().getCanonicalName());
}
}
But, maybe it will be better, to not save the class type, but use method to get type from data?
public Class<T> getType() {
return (Class<T>) data.getClass();
}
public class Response<T> {
private T data;
// other fields & methods
public Class getType() {
return Optional.ofNullable(data).map(Object::getClass).orElse(Void.class);
}
public Optional<Class> getSafeType() {
return Optional.ofNullable(data).map(Object::getClass);
}
}
Super simple, no need to tinker with Jackson, NPE safe...

Generifying array type such as Object[].class

I am trying to generify following class:
public class FooService {
private Client client;
public Foo get(Long id) {
return client.get(id, Foo.class);
}
public List<Foo> query() {
return Arrays.asList(client.get(Foo[].class));
}
}
Everything is alright except Foo[].class:
public abstract class BaseService<T, I> {
private Client client;
private Class<T> type;
public BaseService(Class<T> type) {
this.type = type;
}
public T get(I id) {
return client.get(id, type);
}
public List<T> query() {
return Arrays.asList(client.get(/* What to pass here? */));
}
How can I solve this issue without passing Foo[].class in the constructor like I have done with Foo.class?
Java lacks facilities to obtain an array class from element class directly. A common work-around is to obtain the class from a zero-length array:
private Class<T> type;
private Class arrType;
public BaseService(Class<T> type) {
this.type = type;
arrType = Array.newInstance(type, 0).getClass();
}
You can now pass arrType to the client.get(...) method.
Why don't you do something like this:
public class Client<T> {
T instance;
T get(long id) {
return instance;
}
List<T> get(){
return new ArrayList<>();
}
}
class FooService<T> {
private Client<T> client;
public T get(Long id) {
return client.get(id);
}
public List<T> query() {
return client.get();
}
}

GSON GraphAdapterBuilder fails with interfaces

I am trying to use GraphAdapterBuilder which is an extra to the GSON library to serialize an object with cyclic references. It works great for class but fails when trying to deserialize an interface.
To deserialize interface( which GSON doesn't do by default ) I am using PropertyBasedInterfaceMarshal or InterfaceAdapter. These are registered as custom type adapters for the interfaces.
When using ether above both fail to deserialize the interface as they are only passed the graph id like "0x4" as generated by GraphAdapterBuilder. This is passed as the JsonElement in the deserializer. Obviously there is nothing that can be done with this id from within the deserializer.
Shouldn't these be caught by the GraphAdapterBuilder instead of trying to be deserialized? I have not been able to get around this, is this a bug with GraphAdapterBuilder or is there a way to get around this?
Ok, this is a (working) stub for a solution. It's too late in Italy, to make it nicer.
You need a delegate function like this
package com.google.gson.graph;
/**
* #author Giacomo Tesio
*/
public interface GenericFunction<Domain, Codomain> {
Codomain map(Domain domain);
}
a TypeAdapterFactory like this:
package com.google.gson.graph;
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* #author Giacomo Tesio
*/
public class InterfaceAdapterFactory implements TypeAdapterFactory {
final Map<String, GenericFunction<Gson, TypeAdapter<?>>> adapters;
private final Class<?> commonInterface;
public InterfaceAdapterFactory(Class<?> commonInterface, Class<?>[] concreteClasses)
{
this.commonInterface = commonInterface;
this.adapters = new HashMap<String, GenericFunction<Gson, TypeAdapter<?>>>();
final TypeAdapterFactory me = this;
for(int i = 0; i < concreteClasses.length; ++i)
{
final Class<?> clazz = concreteClasses[i];
this.adapters.put(clazz.getName(), new GenericFunction<Gson, TypeAdapter<?>>(){
public TypeAdapter<?> map(Gson gson) {
TypeToken<?> type = TypeToken.get(clazz);
return gson.getDelegateAdapter(me, type);
}
});
}
}
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type);
if(!this.commonInterface.isAssignableFrom(type.getRawType())
&& !this.commonInterface.equals(type.getRawType()))
{
return delegate;
}
final TypeToken<T> typeToken = type;
final Gson globalGson = gson;
return new TypeAdapter<T>() {
public void write(JsonWriter out, T value) throws IOException {
out.beginObject();
out.name("#t");
out.value(value.getClass().getName());
out.name("#v");
delegate.write(out, value);
out.endObject();
}
#SuppressWarnings({"unchecked"})
public T read(JsonReader in) throws IOException {
JsonToken peekToken = in.peek();
if(peekToken == JsonToken.NULL) {
in.nextNull();
return null;
}
in.beginObject();
String dummy = in.nextName();
String typeName = in.nextString();
dummy = in.nextName();
TypeAdapter<?> specificDelegate = adapters.get(typeName).map(globalGson);
T result = (T)specificDelegate.read(in);
in.endObject();
return result;
}
};
}
}
a pair of tests like these
public final class InterfaceAdapterFactoryTest extends TestCase {
public void testInterfaceSerialization1(){
SampleInterface first = new SampleImplementation1(10);
SampleInterfaceContainer toSerialize = new SampleInterfaceContainer("container", first);
GsonBuilder gsonBuilder = new GsonBuilder();
new GraphAdapterBuilder()
.addType(SampleInterfaceContainer.class)
.addType(SampleImplementation1.class)
.addType(SampleImplementation2.class)
.registerOn(gsonBuilder);
gsonBuilder.registerTypeAdapterFactory(new InterfaceAdapterFactory(
SampleInterface.class, new Class<?>[] { SampleImplementation1.class, SampleImplementation2.class }
));
Gson gson = gsonBuilder.create();
String json = gson.toJson(toSerialize);
System.out.println(json);
SampleInterfaceContainer deserialized = gson.fromJson(json, SampleInterfaceContainer.class);
assertNotNull(deserialized);
assertEquals(toSerialize.getName(), deserialized.getName());
assertEquals(toSerialize.getContent().getNumber(), deserialized.getContent().getNumber());
}
public void testInterfaceSerialization2(){
SampleImplementation2 first = new SampleImplementation2(5, "test");
SampleInterfaceContainer toSerialize = new SampleInterfaceContainer("container", first);
first.Container = toSerialize;
GsonBuilder gsonBuilder = new GsonBuilder();
new GraphAdapterBuilder()
.addType(SampleInterfaceContainer.class)
.addType(SampleImplementation1.class)
.addType(SampleImplementation2.class)
.registerOn(gsonBuilder);
gsonBuilder.registerTypeAdapterFactory(new InterfaceAdapterFactory(
SampleInterface.class, new Class<?>[] { SampleImplementation1.class, SampleImplementation2.class }
));
Gson gson = gsonBuilder.create();
String json = gson.toJson(toSerialize);
System.out.println(json);
SampleInterfaceContainer deserialized = gson.fromJson(json, SampleInterfaceContainer.class);
assertNotNull(deserialized);
assertEquals(toSerialize.getName(), deserialized.getName());
assertEquals(5, deserialized.getContent().getNumber());
assertEquals("test", ((SampleImplementation2)deserialized.getContent()).getName());
assertSame(deserialized, ((SampleImplementation2)deserialized.getContent()).Container);
}
}
and some sample classes (to verify that the tests pass)
public class SampleInterfaceContainer {
private SampleInterface content;
private String name;
public SampleInterfaceContainer(String name, SampleInterface content)
{
this.name = name;
this.content = content;
}
public String getName()
{
return this.name;
}
public SampleInterface getContent()
{
return this.content;
}
}
public interface SampleInterface {
int getNumber();
}
public class SampleImplementation1 implements SampleInterface{
private int number;
public SampleImplementation1()
{
this.number = 0;
}
public SampleImplementation1(int number)
{
this.number = number;
}
public int getNumber()
{
return this.number;
}
}
public class SampleImplementation2 implements SampleInterface{
private int number;
private String name;
public SampleInterfaceContainer Container;
public SampleImplementation2()
{
this.number = 0;
this.name = "";
}
public SampleImplementation2(int number, String name)
{
this.number = number;
this.name = name;
}
public int getNumber()
{
return this.number;
}
public String getName()
{
return this.name;
}
}
While this has been a quick&dirty hack, it works like a charme.
You just have to pay attention at the order of the operations during the initialization of GsonBuilder. You have to initialize and register the GraphAdapterBuilder first and only after register this factory.
It has been funny (if a bit tricky since I'm not a Java expert).

JSON with Jackson: Desirialize fails if abstract methods are used (Polymorphic Type Handling)

i have a question concerning Json deserialization with Jackson (edit: 2.0.4 version). I would like serialize an Bean, containing the list of other beans, as string , save this string and then to deserialize later this string. I use the some base class and its subtypes. The basis class Parent is an abstract class, that has two attributes with getters und setters, this class has also an abstract method getType(). Other abstract class AbstractChild inherits from class Parent . This class has attributes too and isExportEnabled() abstract method.
I have no problems, if this Bean will be serialized. I use the following annotation on the Parent class
*#JsonTypeInfo(use = JsonTypeInfo.Id.MINIMAL_CLASS, include = JsonTypeInfo.As.PROPERTY, property = "#cls")*
The string will be generated.
But the desirialize failed: the exception “Unrecognized field "type"”will be thrown. But I need this attribute! I’m tried to set #JsonProperty("type") on abstract method, this has no effect.
Please help me.
edit: if i introduce the private fields "type" (Parent) and "exportEnabled" (AbstractChild) so it runs correctly.
P.S The exception
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:
Unrecognized field "type" (class tst.SimpleTestMain$FirstChild), not
marked as ignorable (4 known properties: , "id", "maxCount", "code",
"minCount"]) at [Source: java.io.StringReader#1ad9fa; line: 1,
column: 125] (through reference chain:
tst.Fam["members"]->tst.FirstChild["type"]) at
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:79)
at
com.fasterxml.jackson.databind.DeserializationContext.reportUnknownProperty(DeserializationContext.java:568)
…and the example class
package tst;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.ObjectMapper;
public class SimpleTestMain {
enum Type {
TYPE_A, TYPE_B
}
#JsonTypeInfo(use = JsonTypeInfo.Id.MINIMAL_CLASS, include = JsonTypeInfo.As.PROPERTY, property = "#cls")
public static abstract class Parent {
private int id;
private String code;
public Parent() {
}
#JsonProperty("type")
// First abstract getter
public abstract Type getType();
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
}
public static abstract class AbstractChild extends Parent {
private int minCount;
private int maxCount;
public AbstractChild() {
}
// Second abstract method: boolean used
public abstract boolean isExportEnabled();
public int getMinCount() {
return minCount;
}
public void setMinCount(int minCount) {
this.minCount = minCount;
}
public int getMaxCount() {
return maxCount;
}
public void setMaxCount(int maxCount) {
this.maxCount = maxCount;
}
}
public static class FirstChild extends AbstractChild {
#Override
public boolean isExportEnabled() {
return false;
}
#Override
public Type getType() {
return Type.TYPE_A;
}
}
public static class SecondChild extends AbstractChild {
#Override
public boolean isExportEnabled() {
return true;
}
#Override
public Type getType() {
return Type.TYPE_B;
}
}
public static class Fam {
private int famId;
private List<Parent> members;
public Fam() {
members = new ArrayList<Parent>();
}
public int getFamId() {
return famId;
}
public void setFamId(int famId) {
this.famId = famId;
}
public List<Parent> getMembers() {
return members;
}
public void setMembers(List<Parent> members) {
this.members = members;
}
public void addMember(Parent member) {
members.add(member);
}
}
public SimpleTestMain() {
}
public static void main(String[] args) {
Fam fam = new Fam();
FirstChild fc = new FirstChild();
fc.setId(1);
fc.setCode("FirstChildCode");
fc.setMinCount(1);
fc.setMaxCount(4);
fam.addMember(fc);
SecondChild sc = new SecondChild();
sc.setCode("SecondChildCode");
sc.setMinCount(131);
sc.setMaxCount(431);
fam.addMember(sc);
String test = "";
// Serialize it
ObjectMapper mapper = new ObjectMapper();
try {
test = mapper.writeValueAsString(fam);
System.out.println("Serialized bean:\n" + test);
// the output
// Serialized bean:
// {"famId":0,"members":[{"#cls":".SimpleTestMain$FirstChild","id":1,"code":"FirstChildCode","minCount":1,"maxCount":4,"type":"TYPE_A","exportEnabled":false},{"#cls":".SimpleTestMain$SecondChild","id":0,"code":"SecondChildCode","minCount":131,"maxCount":431,"type":"TYPE_B","exportEnabled":true}]}
} catch (IOException e) {
e.printStackTrace();
}
// Deserialize it
mapper = new ObjectMapper();
// mapper.enableDefaultTyping();
try {
Fam fam1 = mapper.readValue(test, Fam.class);
} catch (IOException e) {
e.printStackTrace();
}
}
}

Categories

Resources