是否可以为所有 Jersey 资源方法指定默认视图?

Is it possible to specify a default View for all Jersey resource methods?

情况是这样的。

我有一个使用 Jersey 2.17、Jackson 2.6.3 和 Spring 4.2.0 的大型代码库。

我有很多模型,其中一小部分属性通过 @JsonProperty 公开。其余默认排除

有许多 Jersey 资源方法 没有 使用 JsonView 注释。

输入我。我需要编写一些新的内部 API 端点来公开 internal/confidential 模型属性的不同子集。我用 @JsonProperty@JsonView(SuperSecretAndInternal.class).

注释了这些 "private" 属性

原始 public 属性我添加了 @JsonView(PublicForEveryone.class) 注释。

问题是有很多资源方法处理程序不使用指定 JsonView。结果是所有属性(PublicForEveryone 和 SuperSecretAndIntenal 都被公开了。


编辑。添加示例代码。

// POJO - before
@JsonAutoDetect(getterVisibility = NONE, isGetterVisibility = NONE, fieldVisibility = NONE)
class Person {

    @JsonProperty
    String name;
    @JsonProperty
    String age;

    Date createdDate;
    String socialSecurityNumber;

    // getters/setters not shown
}

这在 PublicAPIResource

中的 Jersey 方法处理程序中使用
@GET
@Path("/people")
public Person getUser(@PathParam("name") String name)
{
// get user by name, return user
}

并导致 json:

{ name: "Jane", age: 20 }

现在,我来了,想在备用和private/internal API中暴露POJO的敏感字段。所以我像这样修改 POJO:

// POJO - after
@JsonAutoDetect(getterVisibility = NONE, isGetterVisibility = NONE, fieldVisibility = NONE)
class Person {

    @JsonProperty
    @JsonView(PublicForEveryone.class)
    String name;

    @JsonProperty
    @JsonView(PublicForEveryone.class)
    String age;

    @JsonProperty
    @JsonView(SuperSecretAndInternal.class)
    Date createdDate;

    @JsonProperty
    @JsonView(SuperSecretAndInternal.class)
    String socialSecurityNumber;

    // getters/setters not shown
}

创建视图时:

public class Views
{

    public static class PublicForEveryone
    {}
    public static class SuperSecretAndInternal extends PublicForEveryone
    {}
}

然后我在 PrivateAPIResource

中创建了 一个新的 Jersey 资源处理程序
@GET
@Path("/internal/secret/people")
@JsonView( SuperSecretAndInternal.class )
public Person getUser(@PathParam("name") String name)
{
// get user by name, return user
}

哪个 returns json:

{ name: "Jane", age: 20, createdDate: xxx, socialSecuritynumber: 123  }

但是 原来的 PublicAPIResource 现在 returns 整个 Person POJO,因为它没有 @JsonView 注解。在这个简单的示例中,我可以简单地添加注释并完成,但在我的真实代码库中,有很多资源,更不用说 People POJO 是其他模型中的嵌套字段的实例。


问题:有没有办法为POJO/model指定一个默认 JsonView?目的是如果球衣资源方法处理程序未指定 @JsonView,则将使用默认值,而不是仅公开每个 @JsonProperty 注释 属性.

如果没有,有没有人知道我可以通过另一种方式实现此目的,而无需修改我所有的资源方法处理程序(因为我不能)?

我可以为 POJO 提供一个默认的序列化器,用 "default" 视图序列化它,但以某种方式允许显式视图通过吗?

您可以配置默认值inclusion/exclusion,但我认为这不能解决您的问题。您检查过 JsonFilter http://wiki.fasterxml.com/JacksonFeatureJsonFilter 了吗,它具有定义默认过滤器的功能,可以应用于所有 pojos/models.

示例 pojo:

class Person{
    String name;
    String age;
    Date createdDate;
}
class User{
    String username;
    String password;
    Date createdDate;
}

CustomAnnotationInspector:

public class CustomIntrospector extends JacksonAnnotationIntrospector
{
  @Override
  public Object findFilterId(AnnotatedClass ac) {
    // Let's default to current behavior if annotation is found:
    Object id = super.findFilterId(ac);
    // but use simple class name if not
    if (id == null) {
       id = "DEFAULT_FILTER";
    }
    return id;
}

将它连接到您的 ObejctMapper:

ObjectMapper mapper = new ObjectMapper();

// create filter with id "DEFAULT_FILTER" and configure it to exclude 'createdDate' property.
FilterProvider filters = new SimpleFilterProvider().addFilter("DEFAULT_FILTER",
SimpleBeanPropertyFilter.serializeAllExcept("createdDate"));

JacksonAnnotationIntrospector jai = new CustomIntrospector ();

// plug the custom annotation that will use "DEFAULT_FILTER" if the pojo doesn't have @JsonFilter annotation.
String jsonPerson = mapper.setAnnotationIntrospector(jai).writer(filters).writeValueAsString(new Person());
String jsonUser = mapper.setAnnotationIntrospector(jai).writer(filters).writeValueAsString(new User());