Да, вы можете установить имя элемента в зависимости от универсального типа с помощью пользовательского сериализатора .
Имейте в виду, что Джексон использует методы get
для именования свойствсериализованный json / xml, поэтому вы получаете элемент roomDetails
в вашем сериализованном xml.
Аннотации типа @JsonGetter
и @JsonProperty
ожидают постоянного значения, поэтому их нельзя использовать в этом случае, потому что мыможно просто определить тип во время выполнения.
Решение:
Room
класс, помеченный @JsonSerialize
:
@JsonSerialize(using = RoomSerializer.class)
public class Room<T> {
private int roomId;
private String roomName;
private T roomDetails;
public int getRoomId() {
return roomId;
}
public void setRoomId(int roomId) {
this.roomId = roomId;
}
public String getRoomName() {
return roomName;
}
public void setRoomName(String roomName) {
this.roomName = roomName;
}
public T getRoomDetails() {
return roomDetails;
}
public void setRoomDetails(T roomDetails) {
this.roomDetails = roomDetails;
}
}
Классы типа Bathroom
и Livingroom
остаются неизменными.
RoomSerializer
реализация:
public class RoomSerializer extends StdSerializer<Room> {
public RoomSerializer() {
this(null);
}
public RoomSerializer(Class<Room> t) {
super(t);
}
@Override
public void serialize(Room value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
jgen.writeStartObject();
jgen.writeNumberField("roomId", value.getRoomId());
jgen.writeStringField("roomName", value.getRoomName());
// Here we determine the field name depending on the type
String roomDetailsFieldName = value.getRoomDetails().getClass().getSimpleName();
jgen.writeObjectField(roomDetailsFieldName, value.getRoomDetails());
jgen.writeEndObject();
}
}
И с вашим примером вы получите то, что вы желаете:
<Room>
<roomId>10</roomId>
<roomName>MyRoom</roomName>
<Livingroom>
<hasCouch>true</hasCouch>
<numOfSeats>5</numOfSeats>
</Livingroom>
</Room>