You could use @JsonView
. That's probably the easiest solution, as @JsonView
works out-of-the-box with JAX-RS.
Alternativerly, it could be achieved with a BeanPropertyFilter
, similar to another solution I put together a while ago.
Start defining your annotation:
@Documented
@Retention(RUNTIME)
@Target({FIELD})
public @interface HiddenForRoles {
String[] value();
}
Then define your BeanPropertyFilter
, which can extend SimpleBeanPropertyFilter
:
public class HiddenForRolesPropertyFilter extends SimpleBeanPropertyFilter {
private String allowedRole;
public HiddenForRolesPropertyFilter(String allowedRole) {
this.allowedRole = allowedRole;
}
@Override
public void serializeAsField(Object pojo, JsonGenerator jgen,
SerializerProvider provider,
PropertyWriter writer) throws Exception {
HiddenForRoles hiddenForRoles = writer.getAnnotation(HiddenForRoles.class);
if (hiddenForRoles != null) {
if (Arrays.asList(hiddenForRoles.value()).contains(allowedRole)) {
writer.serializeAsOmittedField(pojo, jgen, provider);
return;
}
}
// If no annotation is provided, the property will be serialized
writer.serializeAsField(pojo, jgen, provider);
}
}
Place the @HiddenForRoles
annotation in your fields, according to your needs and ensure the class is annotated with @JsonFilter
:
@Data
@JsonFilter("hiddenForRolesPropertyFilter")
public class Foo {
private String bar;
@HiddenForRoles({"cat"})
private String biz;
}
Finally, register the filter in a ContextResolver
for ObjectMapper
:
String currentUserRole = // Get role from the current user
FilterProvider filterProvider = new SimpleFilterProvider()
.addFilter("hiddenForRolesPropertyFilter",
new HiddenForRolesPropertyFilter(currentUserRole));
ObjectMapper mapper = new ObjectMapper();
mapper.setFilterProvider(filterProvider);
If you want to make your filter "global", that is, to be applied to all beans, you can create a mix-in class and annotate it with @JsonFilter
:
@JsonFilter("hiddenForRolesPropertyFilter")
public class HiddenForRolesPropertyFilterMixIn {
}
Then bind the mix-in class to Object
:
mapper.addMixIn(Object.class, HiddenForRolesPropertyFilterMixIn.class);