T - the type of objects on which this view will be applied.public interface BeanView<T>
The BeanView tries to solve this kind of problem by taking the second approach. Indeed
implementations of BeanView will act as a stateless bean that will extract data (and could apply
transformations) during serialization and as a factory and data aggregator during
deserialization. The parameterized type T will correspond to the type of the objects on which
this view can be applied. All the methods from the view respecting the conventional JavaBean
structure will be used (getters to extract data, setters to aggregate and static methods
annotated with Creator as factory methods). Except that the
getters will take an argument of type T (from which to extract the data), and the setter two
arguments, the value (can be a complex object, in that case Genson will try to deserialize the
current value into that type) and T object in which to set the data. Parameters order matters,
for setters the first parameter is the value to deserialize and the second is the object that you
are building (of type T). By default the beanview functionality is disabled, to enable it use
method setWithBeanViewConverter(true) from Genson.Builder. Lets have a look at this example to better
understand how it works.
public static class Person {
private String lastName;
String name;
int birthYear;
String thisFieldWontBeSerialized;
Person(String lastName) {
this.lastName = lastName;
}
public String getLastName() {
return lastName;
}
// instead of serializing and deserializing Person based on the fields and methods it contains those
// and only those from the BeanView will be used
public static class ViewOfPerson implements BeanView<Person> {
public ViewOfPerson() {
}
// This method will be called to create an instance of Person instead of using the constructor
// or annotated @Creator method from Person
@Creator
public static Person createNewPerson(String lastName) {
return new Person(lastName);
}
public String getLastName(Person p) {
return p.getLastName();
}
public @JsonProperty("name")
String getNameOf(Person p) {
return p.name;
}
// here we will transform the birth year of the person into its age and change the serialized
// name from "birthYear" to "age"
public int getAge(Person p) {
return GregorianCalendar.getInstance().get(Calendar.YEAR) - p.birthYear;
}
public void setName(String name, Person p) {
p.name = name;
}
// here it will match the property named "age" from the json stream and transform it into birth
// year of Person
@JsonProperty("age")
public void setBirthYear(int personBirthYear, Person p) {
p.birthYear = GregorianCalendar.getInstance().get(Calendar.YEAR) - personBirthYear;
}
}
public static void main(String[] args) {
Genson genson = new Genson.Builder().setWithBeanViewConverter(true).create();
genson.serialize(new Person("eugen"), ViewOfPerson.class);
}
Implementations of BeanView must be stateless, thread safe and have a default no arg constructor. BeanViews will be applied at runtime before the standard Converter. If a view for the current type is present in the context it will be used instead of the corresponding Converter. If you want to understand how it works behind the scene you can have a look at BeanViewConverter and BeanViewDescriptorProvider.
Copyright © 2014. All Rights Reserved.