JSON,Jackson

마자나다·2023년 10월 21일
0

네트워크

목록 보기
3/5

JSON이란?

  • JSON은 JavaScript Object Notation의 약자로 데이터 교환을 위한 경량의 텍스트 기반형식이다.
  • JSON은 다양한 응용 분야에서 데이터교환과 저장을 위해 널리 사용된다. 웹 어플리케이션, 웹API, 데이터 저장 구성 및 파일 등등 매우 다양한곳에 사용된다.

JSON의 특징

  • 가독성과 간결성 : JSON은 사람이 읽고 쓰기에 용이한 형식으로 텍스트로 표현되어 있다.
  • 계층 구조 : JSON 데이터는 계층 구조로 표현된다. 객체와 배열을 중첩하여 사용한 복잡한 데이터 구조를 표현할 수 도 있다.
  • 데이터 타입 : JSON은 다양한 데이터 타입을 지원한다. 문자열, 숫자, 불린, 객체, 배열, Null등이 있다.
  • 키-값 쌍 : JSON객체는 키와 값 쌍으로 구성된다. 키는 문자열이여야하고, 값은 다양한 데이터타입을 지원한다.
  • 경량 및 빠른 파싱 : JSON은 경량 형식이며, 데이터를 빠르게 파싱하고 생성할 수 있다. 이는 웹브라우저와 서버간의 빠른 데이터 교환에 이점을 제공한다.

Jackson이란?

  • Jackson은 Java언어용 JSON처리 라이브러리이다. JSON데이터와 Java 객체간의 변환을 용이하게 만들어준다. JSON을 쉽게 사용하기 위해 나온 라이브러리라고 보면 된다.

Jackson의 특징

  • 스트림 방식으로 속도가 빠르고 유연하다. 그리고 대용량 데이터를 효율적으로 처리할 수 있다.
  • 어노테이션 방식으로 사용이 가능하며 각종 문서화와 유효성 체크를 쉽게 가능하게 해준다.
  • JSON데이터를 파싱하여 Java객체로 변환하거나, Java객체를 Json형식의 문자열로 생성하는 기능을 제공한다.
  • Jackson은 JSON데이터의 키와 값을 Java클래스의 필드나 메서드를 매핑하여, 객체로 변환한다.

Jackson에서 자주 사용되는 메서드

  • ObjectMapper : ObjectMapper은 JSON데이터를 Java객체로 변환하거나 Java객체를 JSON데이터로 변환하기 위한 핵심 클래스이다. writeValueAsString()메서드를 사용하여 JsonString으로 바꾸어 직렬화 한다.
  1. JavaObject -> jsonString 변환
ObjectMapper objectMapper = new ObjectMapper();
JavaObject javaObject = new JavaObject("Alice", 25);
String jsonString = objectMapper.writeValueAsString(javaObject);
  1. jsonString -> JavaObject 변환
JavaObject javaObject = objectMapper.readValue(jsonString,JavaObject.class);

readValue메서드를 사용하여 변환을 원하는 jsonString을 넣고, 원하는 class형식으러 넣음으로 변환된다.

  1. JsonString -> Map 변환
Map<String,Object> jsonMap = objectMapper.readValue(jsonStr, new TypeReference<Map<String,Object>>(){});
  1. JsonArrayString -> JavaObject
Student[] studentArr = objectMapper.readValue(jsonArrStr, JavaObject[].class);
  1. JsonFile -> JavaObject
Student[] studentArr = objectMapper.readValue(jsonArrStr, JavaObject[].class);

Json 다형성 관련 어노테이션

나는 채팅방을 설계해보고 Json을 사용해서 다시 설계해본적이 있다.
그런데 여기서 클라이언트->서버 , 서버->클라이언트 이렇게 두분류로 나누어서 패킷을 주고받도록 설계하였고
패킷은 템플릿메서드 방식을 사용해서 공통된 부분을 정리하고 각자가 다른특성이 있는 부분은 상속을받아서 해결하였다.
그런데 Json을 사용할려고하니 다형성에 있어서 문제가 생겼다. 이에 따른 해결을 하기 위해 사용한 방법을 알아보자


헤더패킷에 다음과 같은 내용의 어노테이션을 넣었다.

  • JsonTypeInfo
    JsonTypeInfo는 직렬화 시 포함할 타입 정보의 세부사항을 나타낸다.
@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는 서브클래스에 모드 등록되어야 실제 동작을한다. 서브클래스를 알려주기 위해 사용되는 어노테이션이다.
@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
@JsonTypeName("CLIENT_MESSAGE")
public class ClientMessagePacket extends HeaderPacket {

서브클래스에 쓰이며 JsonSubTypes에 쓰인 name과 비교하여 이름을 확인한 뒤, 매핑 된다.

  • JsonProperty
    JsonProperty는 Java 객체의 필드 또는 메서드를 JSON속성과 매핑하는데 사용된다.
public ClientMessagePacket(@JsonProperty("message") String message, @JsonProperty("name") String name) {
        super(PacketType.CLIENT_MESSAGE);
        this.message = message;
        this.name = name;
    }

클래스를 정의하고 @JsonProperty를 사용하여 매핑을 지정할수있다.

다음과같은 방법으로 다형성문제를 해결하였다.

출처 및 참고

https://hianna.tistory.com/631

profile
우왕좌왕 개발

0개의 댓글

관련 채용 정보