Итак, давайте представим, что у нас есть компания, которая продает страховые полисы. Многие агенты могут видеть одну политику, но каждый агент имеет свою собственную роль в каждой политике, поэтому он должен видеть только ограниченные данные.
@FilterableResource(fieldWithRole = "role") //my annotation @JsonFilter("filterable") inside
public class Policy {
private String number;
@FilterByRole(role = "MAIN_AGENT") //only for main
private String cost;
@FilterByRole(role = "MAIN_AGENT") //only for main
private Person insurer;
private Person insured;
@JsonIgnore
private String role; // for no one
}
public class Person {
private String name;
@FilterByRole(role = "MAIN_AGENT")
private String mobile; //only for main
}
эти политики возвращаются из простого результата конечной точки отдыха / API / политик для результатаагент X:
[
{
"number": "123",
"cost": 123000,
"insurer": [{"name": "John", "mobile": "443456434"}],
"insured": [{"name": "Jey", "mobile": "13124124234"}],
"role": "MAIN_AGENT"
},
{
"number": "321",
"cost": 321000,
"insurer": [{"name": "Betty", "mobile": "14212442"}],
"insured": [{"name": "Frank", "mobile": "32523523"}],
"role": "AGENT"
}
]
результат должен быть отфильтрован в соответствии с моими аннотациями к:
[
{
"number": "123",
"cost": 123000,
"insurer": [{"name": "John", "mobile": "443456434"}],
"insured": [{"name": "Jey", "mobile": "13124124234"}],
},
{
"number": "321",
"insured": [{"name": "Frank"}],
}
]
, поэтому я решил, что могу отфильтровать их непосредственно перед отправкой обратно, используя фильтр Джексона (вот почемуЯ использовал JsonFilter). Вдохновение было @JsonView (Role.class), но проблема в том, что каждое поле не основано на контексте аутентификации (которое никогда не меняется), а в моем случае основано на каждом объекте политики, поэтому я ввел дополнительный FilterableResource, который даст мнезначение для каждой политики.
Мой фильтр Джексона выглядит следующим образом:
private SimpleBeanPropertyFilter filter() {
return new SimpleBeanPropertyFilter() {
@Override
public void serializeAsField(Object pojo, JsonGenerator jgen, SerializerProvider provider, PropertyWriter writer) throws Exception {
String resourceMandatoryRole = getRoleBasedOnFilterableAnnotation(pojo);
List<String> fieldMandatoryRoles = getRoleBasedOnFilterByAnnotation(writer);
if (fieldMandatoryRoles.isEmpty() || fieldMandatoryRoles.contains(resourceMandatoryRole) ) {
super.serializeAsField(pojo, jgen, provider, writer);
}
}
};
}
Он даже работает, но, к сожалению, только для корневого уровня, он не может входить в класс пользователя, более того, это только предварительный просмотр моегопроблема, у меня гораздо более сложный случай со многими вложенными объектами, поэтому:
- было бы неплохо не создавать еще одну аннотацию, которая говорит @GoInside, чтобы помочь войти в дочерние классы
- Я нехотите использовать эти расширения для JsonFilter для исключения дочерних полей, как они выглядят как @JsonFilter ("Object.Object.Object.Object.field")
Есть идеи?