jackson:忽略getter,但不能使用@JsonView

Ant*_*nov 8 java serialization json jackson json-view

我正在寻找仅在某些情况下序列化瞬态信息的可能性:

@JsonInclude(Include.NON_NULL)
@Entity
public class User {

    public static interface AdminView {}

    ... id, email and others ...

    @Transient
    private transient Details details;

    @JsonIgnore                  // Goal: ignore all the time, except next line
    @JsonView(AdminView.class)   // Goal: don't ignore in AdminView
    public Details getDetails() {
        if (details == null) {
            details = ... compute Details ...
        }
        return details;
    }
}

public class UserDetailsAction {
    private static final ObjectWriter writer = new ObjectMapper();
    private static final ObjectWriter writerAdmin = writer
        .writerWithView(User.AdminView.class);

    public String getUserAsJson(User user) {
        return writer.writeValueAsString(user);
    }

    public String getUserAsJsonForAdmin(User user) {
        return writerAdmin.writeValueAsString(user);
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我调用getUserAsJson,我希望看到id,email和其他字段,但不是详细信息.这很好用.但我看到getUserAsJsonForAdmin也一样,也没有细节.如果我删除@JsonIgnore注释 - 我确实看到两个调用中的详细信息.

我有什么不对,有好的方法吗?谢谢!

Ale*_*lov 5

您可能会发现动态Jackson过滤器的使用稍微优雅一些​​.以下是基于共享一个对象映射器实例的自定义注释过滤POJO字段的示例:

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

}
Run Code Online (Sandbox Code Playgroud)

输出:

{
  "email" : "email"
}
{
  "email" : "email",
  "details" : "secret"
}
Run Code Online (Sandbox Code Playgroud)