使用RESTEasy和Jackson,是否可以在我的模型中使用@RolesAllowed
注释,以避免某些属性在输出中被序列化,具体取决于用户的角色?
我已经找到了大量关于如何使用Jersey进行此操作的文档,但没有任何关于RESTEasy的文档。
我在此体系结构上被阻止,因此切换库不是一个选项,并且使用自定义ObjectMapper
,因为解释here也不是一个选项,因为模型足够大,也可以标记大型数据集的每个属性以进行正确的序列化非常耗时。另外,这是指Jackson库的旧版本,我不确定如何使用新版本。
修改
具体请参阅this blog post以了解我要完成的工作。请注意,这是特定于Jersey的,到目前为止,我没有找到有关RESTEasy的文档来完成此任务。
答案 0 :(得分:2)
如果您不愿意使用@JsonView
,可以考虑@JsonFilter
。首先需要扩展SimpleBeanPropertyFilter
并根据用户角色控制序列化:
public class RoleBasedPropertyFilter extends SimpleBeanPropertyFilter {
private String allowedRole;
public RoleBasedPropertyFilter(String allowedRole) {
this.allowedRole = allowedRole;
}
@Override
public void serializeAsField(Object pojo, JsonGenerator jgen,
SerializerProvider provider,
PropertyWriter writer) throws Exception {
PermitAll permitAll = writer.getAnnotation(PermitAll.class);
if (permitAll != null) {
serializeAsField(pojo, jgen, provider, writer);
return;
}
DenyAll denyAll = writer.getAnnotation(DenyAll.class);
if (denyAll != null) {
writer.serializeAsOmittedField(pojo, jgen, provider);
return;
}
RolesAllowed rolesAllowed = writer.getAnnotation(RolesAllowed.class);
if (rolesAllowed != null) {
if (!Arrays.asList(rolesAllowed.value()).contains(allowedRole)) {
writer.serializeAsOmittedField(pojo, jgen, provider);
return;
}
}
// If no annotation is provided, the property will be serialized
serializeAsField(pojo, jgen, provider, writer);
}
}
要将过滤器应用于某个bean,请使用@JsonFilter("roleBasedPropertyFilter")
注释:
@JsonFilter("roleBasedPropertyFilter")
public class User {
private String firstName;
private String lastName;
private String email;
private String password;
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
@RolesAllowed({"ADMIN"})
public String getEmail() {
return email;
}
@DenyAll
public String getPassword() {
return password;
}
// Other getters and setters
}
然后在ContextResolver
的ObjectMapper
注册您的过滤器:
String currentUserRole = // Get role from the current user
FilterProvider filterProvider = new SimpleFilterProvider()
.addFilter("roleBasedPropertyFilter",
new RoleBasedPropertyFilter(currentUserRole));
ObjectMapper mapper = new ObjectMapper();
mapper.setFilterProvider(filterProvider);
如果你想使你的过滤器" global",即要应用于所有bean,你可以创建一个混合类并用@JsonFilter("roleBasedPropertyFilter")
注释它:
@JsonFilter("roleBasedPropertyFilter")
public class RoleBasedPropertyFilterMixIn {
}
然后将混合类绑定到Object
:
mapper.addMixIn(Object.class, RoleBasedPropertyFilterMixIn.class);