Add dynamic fields to Spring JSON view response

When you cannot modify the domain object's class, you can enrich your JSON with "virtual" fields using a mix-in.

For example, you could create a class named UserMixin that hides the firstName and lastName fields and that exposes a virtual fullName field:

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();
}

Then you would implement a class named UserFullName that extends VirtualBeanPropertyWriter to provide the virtual field's value:

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);
    }
}

Finally, you would need to register your mix-in with the ObjectMapper as shown in the following JUnit test:

@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")));
}

The output is then:

{"fullName":"Frodo Baggins","createdDate":1485036953535}

How about using 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 will just pull all properties of User to the root level and still have the own properties of UserViewA in there.