Is it possible to deserialize only fields from interface
public interface B {
String getB();
}
public interface A {
String getA();
}
public class Impl implements A, B {
@Override
public String getA() {
return "stringA";
}
@Override
public String getB() {
return "stringB";
}
public static void main(String[] args) {
ObjectMapper mapper = new ObjectMapper();
A implA = new Impl();
B implB = new Impl();
String jsonA = null;
String jsonB = null;
try {
jsonA = mapper.writeValueAsString(implA);
jsonB = mapper.writeValueAsString(implB);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
System.out.println(jsonA);
System.out.println();
System.out.println(jsonB);
}
}
What i expected was
Interface A
{"a":"stringA"}
Interface B
{"b":"stringB"}
What i get is
{"a":"stringA","b":"stringB"}
{"a":"stringA","b":"stringB"}
It is possible for one interface, with this annotation @JsonSerialize(as=A.class), but it only works for the first interface. The output with @JsonSerialize is
{"a":"stringA"}
{"a":"stringA"}
Have a look at the JsonIgnore annotation.
https://fasterxml.github.io/jackson-annotations/javadoc/2.7/com/fasterxml/jackson/annotation/JsonIgnore.html
Update
Jackson's @JsonView may fit your requirements. Below are some good articles describing the use case.
Jackson Change JsonIgnore Dynamically
http://www.baeldung.com/jackson-json-view-annotation
Code Sample
public class Sandbox {
public static void main(String[] args) {
ObjectMapper mapper = new ObjectMapper();
A implA = new Impl();
B implB = new Impl();
String jsonA = null;
String jsonB = null;
try {
ObjectWriter jsonAWriter = mapper.writerWithView(A.class);
jsonA = jsonAWriter.writeValueAsString(implA);
ObjectWriter jsonBWriter = mapper.writerWithView(B.class);
jsonB = jsonBWriter.writeValueAsString(implB);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
System.out.println(jsonA);
System.out.println();
System.out.println(jsonB);
}
public interface A {
String getA();
}
public interface B {
String getB();
}
public static class Impl implements A, B {
@Override
@JsonView(A.class)
public String getA() {
return "stringA";
}
@Override
@JsonView(B.class)
public String getB() {
return "stringB";
}
}
}
Output:
{"a":"stringA"}
{"b":"stringB"}
There's no way to do that based on polymorphism principles. Below is the long proof and some alternative approach.
Your implA and implB are references to the objects of the same type. And they are serialized by the same serializer. And they both are instances of A, B and Impl at the same time. There is no way for serializer method to find out what is the type you want it to serialize as. It only can check the the real type with .class (default behavior). It also can parse annotations to find out what class you want it to be serialized as, and to check if it is really instance of that type. That's all it can.
Though it also can use some reflection to find some additional information about the object and it's class, but there's just no information about the type of the variable you declared in your main() method.
Variable type normally is not available at runtime, it is compilation time check. Though, in Java world, it may be available somewhere inside JVM, or as debug information, I'm not sure. But there's definitely no programmatic access from the callable method to a calling method.
So you can choose exactly one way how to serialize single class with single serializer, using @JsonSerialize(as=A.class) annotation.
Or you can implement your own serializer, which will use different superclasses based on some busyness logic, but not based on polymorphism.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With