情况就是这样。
我有一个使用Jersey 2.17,Jackson 2.6.3和Spring 4.2.0的大型代码库。
我有很多模型,其中有一小部分属性用@JsonProperty公开。其余的被默认排除在外。
使用JsonView
注释的不的Jersey资源方法很多。
输入我。我需要编写一些新的内部API端点,这些端点公开内部/机密模型属性的不同子集。我已使用@JsonProperty
和@JsonView(SuperSecretAndInternal.class)
注释了这些“私有”属性。
我添加了@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 }
现在,我来了,并希望在备用和私有/内部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
}
返回json:
{ name: "Jane", age: 20, createdDate: xxx, socialSecuritynumber: 123 }
但原始 PublicAPIResource现在返回整个Person POJO,因为它没有@JsonView注释。在这个简单的例子中,我可以简单地添加注释并完成,但在我的实际代码库中,有许多资源,更不用说People POJO是其他模型中的嵌套字段的实例。
问题:有没有办法为每个POJO /模型指定默认 JsonView?目的是如果一个jersey资源方法处理程序没有指定@JsonView
,那么将使用默认值,而不是仅公开每个@JsonProperty
带注释的属性。
如果没有,有没有人知道我可以实现的另一种方式,而不修改我的所有资源方法处理程序(因为我不能)?
我可以为POJO提供一个默认的序列化程序,使用“默认”视图对其进行序列化,但不知何故允许显式视图通过吗?
答案 0 :(得分:0)
您可以配置默认包含/排除,但我认为这不会解决您的问题。您是否检查过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());