jackson: ignore getter, but not with @JsonView
You may find the use of the dynamic Jackson filtering slightly more elegant for your use case. Here is an example of the filtering of POJO fields based on a custom annotation sharing one object mapper instance:
public class JacksonFilter { static private boolean shouldIncludeAllFields; @Retention(RetentionPolicy.RUNTIME) public static @interface Admin {} @JsonFilter("admin-filter") public static class User { public final String email; @Admin public final String details; public User(String email, String details) { this.email = email; this.details = details; } } public static class AdminPropertyFilter extends SimpleBeanPropertyFilter { @Override protected boolean include(BeanPropertyWriter writer) { // deprecated since 2.3 return true; } @Override protected boolean include(PropertyWriter writer) { if (writer instanceof BeanPropertyWriter) { return shouldIncludeAllFields || ((BeanPropertyWriter) writer).getAnnotation(Admin.class) == null; } return true; } } public static void main(String[] args) throws JsonProcessingException { User user = new User("email", "secret"); ObjectMapper mapper = new ObjectMapper(); mapper.setFilters(new SimpleFilterProvider().addFilter("admin-filter", new AdminPropertyFilter())); System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(user)); shouldIncludeAllFields = true; System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(user)); }}
Output:
{ "email" : "email"}{ "email" : "email", "details" : "secret"}
It's look like jackson have horrible concept on very cool feature like @JsonView. The only way I discover to solve my problem is:
@JsonInclude(Include.NON_NULL)@Entitypublic class User { public static interface BasicView {} public static interface AdminView {} ... id and others ... @JsonView({BasicView.class, AdminView.class}) // And this for EVERY field @Column private String email; @Transient private transient Details details; @JsonView(AdminView.class) public Details getDetails() { if (details == null) { details = ... compute Details ... } return details; }}public class UserDetailsAction { private static final ObjectWriter writer = new ObjectMapper() .disable(MapperFeature.DEFAULT_VIEW_INCLUSION) .writerWithView(User.BasicView.class); private static final ObjectWriter writerAdmin = new ObjectMapper() .disable(MapperFeature.DEFAULT_VIEW_INCLUSION) .writerWithView(User.AdminView.class); public String getUserAsJson(User user) { return writer.writeValueAsString(user); } public String getUserAsJsonForAdmin(User user) { return writerAdmin.writeValueAsString(user); }}
Maybe it's help some one. But I hope to find better solution and because doesn't accept my own answer.
EDIT: because interface can extends (multiple) interfaces, I can use:
public static interface AdminView extends BasicView {}
and just
@JsonView(BasicView.class)
instead of
@JsonView({BasicView.class, AdminView.class})