Вот такая ситуация.
У меня большая кодовая база с использованием Jersey 2.17, Jackson 2.6.3 и Spring 4.2.0.
У меня довольно много моделей с небольшим набором свойств, представленных с помощью @JsonProperty. Остальные по умолчанию исключены.
Есть много методов ресурсов Джерси, которые не используют аннотацию JsonView
.
Внесите меня. Мне нужно написать несколько новых внутренних конечных точек 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.
@GET
@Path("/people")
public Person getUser(@PathParam("name") String name)
{
// get user by name, return user
}
И в результате получаем json:
{ name: "Jane", age: 20 }
Теперь я пришел и хочу предоставить уязвимые поля POJO в альтернативном частном / внутреннем API. Итак, я модифицирую 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
@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 теперь возвращает весь POJO Person, потому что у него нет аннотации @JsonView. В этом простом примере я мог бы просто добавить аннотацию и все готово, но в моей реальной кодовой базе есть много ресурсов, не говоря уже о случаях, когда People POJO является вложенным полем в других моделях.
Вопрос: Есть ли способ указать по умолчанию JsonView для POJO / модели? Намерение таково, что если обработчик метода ресурса jersey НЕ указывает @JsonView
, то будет использоваться значение по умолчанию, вместо того, чтобы просто отображать каждое аннотированное свойство @JsonProperty
.
Если нет, знает ли кто-нибудь другой способ добиться этого без изменения всех моих обработчиков методов ресурсов (потому что я не могу)?
Могу ли я предоставить сериализатор по умолчанию для POJO, который сериализирует его с представлением "по умолчанию", но каким-то образом позволяет явным представлениям проходить через него?
1 ответ
Вы можете настроить включение / исключение по умолчанию, но я думаю, что это не решит вашу проблему. Вы проверяли JsonFilter http://wiki.fasterxml.com/JacksonFeatureJsonFilter, у него есть функция для определения фильтра по умолчанию который может быть применен ко всем pojos / моделям.
Пример 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());
Похожие вопросы
Новые вопросы
java
Java — это высокоуровневый объектно-ориентированный язык программирования. Используйте этот тег, если у вас возникли проблемы с использованием или пониманием самого языка. Этот тег часто используется вместе с другими тегами для библиотек и/или фреймворков, используемых разработчиками Java.