Как изменить JsonView для конкретных свойств
Привет, у меня есть несколько объектов пользовательского интерфейса, которые встроены друг в друга. Пример № 1:
class CarUI {
public UserUI user;
public UserUI agent;
....
public UserUI getUser() {
return user;
}
public UserUI getAgent() {
return agent;
}
}
class UserUI {
@JsonView({Views.Public.class,Views.Private.class})
public String name;
@JsonView({Views.Private.class})
public String phone;
...
}
Как вы можете видеть, если я сериализую UserUI как Public, я выставлю только имя, но для private я выставлю все поля.
Вот мой вопрос: когда я сериализую объект CarUI, я хочу выставить только имя для "пользователя" и имя + телефон для "агента". По сути это означает, что в getter для getUser() я хочу изменить JsonView на Views.Public.class, а для getAgent() я хочу изменить его на Views.Private.class
Есть ли способ перезаписать JsonView в получателях, чтобы теперь вся иерархия возвращаемого объекта сериализовалась с использованием этого нового JsonView?
Отредактировано Как указано ниже, вы можете решить мой пример № 1 с наследованием JsonView. Как насчет более общего. Вот пример № 2:
class CarUI {
public UserUI user;
public UserUI agent;
....
public UserUI getUser() {
return user;
}
public UserUI getAgent() {
return agent;
}
}
class UserUI {
@JsonView({Views.Public.class,Views.Private.class})
public String name;
@JsonView({Views.Private.class})
public String phone;
@JsonView({Views.Public.class})
public String avatarUrl;
...
}
В этом примере я хотел бы отобразить имя + телефон для агента и имя +avatarUrl для пользователя.
2 ответа
@JsonView принимает наследование. Поля Views.Private расширяют поля Views.Public. Это означает, что сериализация Views.Private также будет искать аннотации Views.Public.
public Views {
public Public {}
public Private extends Public {}
}
class CarUI {
public UserUI user;
public UserUI agent;
....
@JsonView(Views.Public.class)
public UserUI getUser() {
return user;
}
@JsonView(Views.Private.class)
public UserUI getAgent() {
return agent;
}
}
class UserUI {
@JsonView(Views.Public.class)
public String name;
@JsonView(Views.Private.class)
public String phone;
...
}
Для примера № 2
Вы можете ввести несколько классов, таких как:
public Views {
public Public {}
public Private1 extends Public {}
public Private2 extends Public {}
}
class CarUI {
public UserUI user;
public UserUI agent;
....
public UserUI getUser() {
return user;
}
public UserUI getAgent() {
return agent;
}
}
class UserUI {
@JsonView(Views.Public.class)
public String name;
@JsonView({Views.Private1.class})
public String phone;
@JsonView({Views.Private2.class})
public String avatarUrl;
...
}
Или вы можете использовать свойства без просмотра и не использовать наследование:
public Views {
public Public {}
public Private {}
}
class CarUI {
public UserUI user;
public UserUI agent;
....
public UserUI getUser() {
return user;
}
public UserUI getAgent() {
return agent;
}
}
class UserUI {
// This one is view-less shows every time unless you specificy
public String name;
@JsonView({Views.Private.class})
public String phone;
@JsonView({Views.Public.class})
public String avatarUrl;
...
}
...
// If you want to hide view-less properties, default is true
objectMapper.configure(SerializationConfig.Feature.DEFAULT_VIEW_INCLUSION, false);
...
Просто нашел более общий случай, если кому-то нужно. По сути, вы можете преобразовать свое свойство внутри геттера, используя другой JsonView, как таковой:
@JsonView({ Views.Detail.class})
public JsonNode getAgent() throws IOException {
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writerWithView(Views. Private.class).writeValueAsString(agent);
return mapper.readTree(json);
}