Solución:
¿Qué tal si usas jackson? @JsonUnwrapped
?
http://fasterxml.github.io/jackson-annotations/javadoc/2.0.0/com/fasterxml/jackson/annotation/JsonUnwrapped.html
public class UserViewA {
@JsonUnwrapped
private User user;
public User getUser() ...
public String getFullName() {
return user.getFirstName() + " " + user.getLastName()
}
}
JsonUnwrapped simplemente llevará todas las propiedades de User al nivel raíz y aún tendrá las propias propiedades de UserViewA allí.
Cuando no puede modificar la clase del objeto de dominio, puede enriquecer su JSON con campos “virtuales” utilizando una combinación.
Por ejemplo, podría crear una clase llamada UserMixin
que esconde el firstName
y lastName
campos y que expone un virtual fullName
campo:
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.annotation.JsonAppend;
import java.util.Date;
@JsonAppend(
prepend = true,
props = {
@JsonAppend.Prop(name = "fullName", value = UserFullName.class)
})
public abstract class UserMixin
{
@JsonIgnore
public abstract String getFirstName();
@JsonIgnore
public abstract String getLastName();
public abstract Date getCreatedDate();
}
Entonces implementaría una clase llamada UserFullName
que se extiende VirtualBeanPropertyWriter
para proporcionar el valor del campo virtual:
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.cfg.MapperConfig;
import com.fasterxml.jackson.databind.introspect.AnnotatedClass;
import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;
import com.fasterxml.jackson.databind.ser.VirtualBeanPropertyWriter;
import com.fasterxml.jackson.databind.util.Annotations;
public class UserFullName extends VirtualBeanPropertyWriter
{
public UserFullName() {}
public UserFullName(BeanPropertyDefinition propDef, Annotations contextAnnotations, JavaType declaredType)
{
super(propDef, contextAnnotations, declaredType);
}
@Override
protected Object value(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception
{
return ((User) bean).getFirstName() + " " + ((User) bean).getLastName();
}
@Override
public VirtualBeanPropertyWriter withConfig(MapperConfig<?> config, AnnotatedClass declaringClass, BeanPropertyDefinition propDef, JavaType type)
{
return new UserFullName(propDef, null, type);
}
}
Finalmente, necesitaría registrar su mezcla con ObjectMapper como se muestra en la siguiente prueba JUnit:
@Test
public void testUserFullName() throws IOException
{
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.addMixIn(User.class, UserMixin.class);
System.out.println(objectMapper.writeValueAsString(new User("Frodo", "Baggins")));
}
La salida es entonces:
{"fullName":"Frodo Baggins","createdDate":1485036953535}