ObjectMapper objectMapper = new ObjectMapper();
JavaObject javaObject = new JavaObject("Alice", 25);
String jsonString = objectMapper.writeValueAsString(javaObject);
JavaObject javaObject = objectMapper.readValue(jsonString,JavaObject.class);
readValue메서드를 사용하여 변환을 원하는 jsonString을 넣고, 원하는 class형식으러 넣음으로 변환된다.
Map<String,Object> jsonMap = objectMapper.readValue(jsonStr, new TypeReference<Map<String,Object>>(){});
Student[] studentArr = objectMapper.readValue(jsonArrStr, JavaObject[].class);
Student[] studentArr = objectMapper.readValue(jsonArrStr, JavaObject[].class);
나는 채팅방을 설계해보고 Json을 사용해서 다시 설계해본적이 있다.
그런데 여기서 클라이언트->서버 , 서버->클라이언트 이렇게 두분류로 나누어서 패킷을 주고받도록 설계하였고
패킷은 템플릿메서드 방식을 사용해서 공통된 부분을 정리하고 각자가 다른특성이 있는 부분은 상속을받아서 해결하였다.
그런데 Json을 사용할려고하니 다형성에 있어서 문제가 생겼다. 이에 따른 해결을 하기 위해 사용한 방법을 알아보자
헤더패킷에 다음과 같은 내용의 어노테이션을 넣었다.
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
use : JsonTypeInfo.Id.NAME는 클래스의 이름을 사용하여 객체의 유형정보를JSON데이터에 포함합니다.
include : JsonTypeInfo.As.PROPERTY는 유형 정보를 JSON데이터의 속성으로 넣는다.
property : “type”라는 이름의 속성을 사용하여 유형 정보를 저장한다.
@JsonSubTypes({
@JsonSubTypes.Type(value = ClientConnectPacket.class, name = "CLIENT_CONNECT"),
@JsonSubTypes.Type(value = ClientMessagePacket.class, name = "CLIENT_MESSAGE"),
@JsonSubTypes.Type(value = ClientDisconnectPacket.class, name = "CLIENT_DISCONNECT"),
@JsonSubTypes.Type(value = ClientChangeNamePacket.class, name = "CLIENT_CHANGENAME"),
@JsonSubTypes.Type(value = ClientWhisperPacket.class, name = "CLIENT_WHISPERMESSAGE"),
@JsonSubTypes.Type(value = ServerDisconnectPacket.class, name = "SERVER_DISCONNECT"),
@JsonSubTypes.Type(value = ServerExceptionPacket.class, name = "SERVER_EXCEPTION"),
@JsonSubTypes.Type(value = ServerMessagePacket.class, name = "SERVER_MESSAGE"),
@JsonSubTypes.Type(value = ServerNameChangePacket.class, name = "SERVER_CHANGENAME"),
@JsonSubTypes.Type(value = ServerNotifyPacket.class, name = "SERVER_NOTIFY"),
@JsonSubTypes.Type(value = ClientFilePacket.class, name = "CLIENT_FILE"),
@JsonSubTypes.Type(value = ServerFilePacket.class, name = "SERVER_FILE")
})
value : 어떤 하위클래스가 매핑되어야하는지 지정한다. 이 값으로 하위 클래스의 클래스 객체를 참조한다.
name : 하위클래스를 식별하는 문자열로 사용된다.
하위클래스마다 @JsonTypeName을 사용해서 name과 비교하여 어느 하위클래스에 쓰여야하는지 구별하여야 한다.
아래는 하위클래스에 사용된 어노테이션이다.
@JsonTypeName("CLIENT_MESSAGE")
public class ClientMessagePacket extends HeaderPacket {
서브클래스에 쓰이며 JsonSubTypes에 쓰인 name과 비교하여 이름을 확인한 뒤, 매핑 된다.
public ClientMessagePacket(@JsonProperty("message") String message, @JsonProperty("name") String name) {
super(PacketType.CLIENT_MESSAGE);
this.message = message;
this.name = name;
}
클래스를 정의하고 @JsonProperty를 사용하여 매핑을 지정할수있다.
다음과같은 방법으로 다형성문제를 해결하였다.
출처 및 참고