Spring

[Java / Spring] ObjectMapper 사용하여 JSON 파싱하기

JWonK 2022. 5. 22. 18:22
728x90
반응형

스프링을 공부하면서 개발을 하다보면 내가 보낸 request에 대한 response가 JSON인 경우가 상당히 많다.

이럴 경우 다시 JSON에서 내가 사용하고자 하는 데이터를 객체 형태로 가져와야하는데 이 때 많이 사용하는 것이 Jackson 라이브러리의 ObjectMapper 클래스이다.

 

따라서, 내가 하고자 하는 개발에서 올바른 ObjectMapper 사용을 위해 ObjectMapper가 무엇인지 정리해보려한다.

 


▶ ObjectMapper란 무엇일까?

  • JSON 컨텐츠 / 객체를 Java 객체로 deserialization(역직렬화) 하거나 Java 객체를 JSON형태로 serialization(직렬화)할 때 사용하는 Jackson 라이브러리의 클래스이다.
  • ObjectMapper는 생성 비용이 비싸기 때문에 bean / static 으로 처리하는 것을 권장한다.

 

직렬화 (Serialize)

→ 데이터를 전송하거나 저장할 때 바이트 문자열이어야 하기 때문에 객체들을 문자열로 바꾸어 주는 것

 

역직렬화 (Deserialize)

→ 데이터가 모두 전송된 이후, 수신 측에서 다시 문자열을 기존의 객체로 변환하는 작업

 

@RestController의 경우, request와 response가 내부적으로 직렬화 / 역직렬화가 되는데 이는 jackson 라이브러리 때문

 


ObjectMapper를 사용하여 읽기 및 쓰기

 

JSON Java Object

 JSON 컨텐츠를 Java 객체로 역직렬화 하기 위해서는 ObjectMapper의 readValue() 메서드를 사용한다.

@Slf4j
@Component
@RequiredArgsConstructor
public class WebSockChatHandler extends TextWebSocketHandler {

    private final ObjectMapper objectMapper;
    private final ChatService chatService;

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        String payload = message.getPayload();
        log.info("payload {}", payload);

        ChatMessage chatMessage = objectMapper.readValue(payload, ChatMessage.class);
        ChatRoom room = chatService.findRoomById(chatMessage.getRoomId());
        room.handleActions(session, chatMessage, chatService);

    }
}

Override된 handleTextMessage 메서드 내 objectMapper.readValue()가 존재한다.

웹 소켓 통신에서 전송되는 메세지는 TextMessage에 받아주고 이를 getPayload()를 통해 제네릭 타입<T>으로 받을 수 있다. 위에서는 payload라는 String 객체에 담아주었다.

 

이제 이를 Java 객체에 담아주기 위해 ObjectMapper에 payload를 담아주고, 다시 지정 타입으로 ChatMessage.class를 지정하여 ChatMessage로 변환시켜준 것이다.

 

@Getter @Setter
public class ChatMessage {

    // 메세지 타입 : 입장, 채팅
    public enum MessageType{
        ENTER, TALK
    }

    private MessageType type;   // 메세지 타입
    private String roomId;      // 방 번호
    private String sender;      // 메세지 보낸 사람
    private String message;     // 메세지
}

위 객체가 JSON을 Java Object로 받고자했던 객체형태이다.

 

 

참고 : https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/socket/TextMessage.html

 

TextMessage (Spring Framework 5.3.20 API)

TextMessage public TextMessage(CharSequence payload, boolean isLast) Create a new text WebSocket message with the given payload representing the full or partial message content. When the isLast boolean flag is set to false the message is sent as partial

docs.spring.io

 


 

Java Object JSON

Java 객체를 Json으로 직렬화하기 위해서는 ObjectMapper의 writeValue() 메서드를 사용한다.

public class ObjectMapperExample {
    public static void main(String[] args) {
    
        ObjectMapper objectMapper = new ObjectMapper();

	// Java Object ->  JSON
        Member member = new Member("ChulSu Kim", 20, "Seoul");
        try {
            objectMapper.writeValue(new File("src/member.json"), member);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

위 코드를 보면 먼저 JSON으로 저장하고자 하는 객체 member가 존재한다.

 

그리고 objectMapper.writeValue를 통해 JSON으로 변환하고자 한다. writeValue 파라미터에는 JSON을 저장할 파일과 변환시킬 Java 객체(member)를 넣어준다.

 

여기서 주의할 점이 있는데 JSON으로 직렬화 시킬 클래스에는 Getter가 존재해야한다.

 

Jackson 라이브러리는 Getter와 Setter를 이용하여 prefix를 잘라내고 맨 앞을 소문자로 만드는 것으로 필드를 식별한다.

 

따라서 직렬화 시킬 클래스에 Getter가 존재하지 않으면 클래스에서 필드를 식별하지 못하고 결국 값을 파싱하지 못하여 에러가 발생하게 된다.

 

정상실행을 하면 첫 번째 파라미터로 넘겨주었던 경로에 JSON 파일이 생성된다.

 

 

참고

https://velog.io/@zooneon/Java-ObjectMapper%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%98%EC%97%AC-JSON-%ED%8C%8C%EC%8B%B1%ED%95%98%EA%B8%B0

 

728x90
반응형