본문 바로가기
별밤 일지/개발

[Java] JsonPath, ObjectMapper

by 별밤 에디터 2024. 6. 10.

 

지난 시간에 ObjectMapper 에 대해 설명했다.

 

 

 

ObjectMapper 는 객체로부터 Json 형태의 문자열을 만들어내고, 역으로 Json 형태의 문자열로 객체를 만들 수 있기 때문에 로깅할 때 유용할 때 사용할 수 있다.

예를 들어 dto 를 그냥  System.out.println();  로 출력하면 형태가 보기 좋지 않다. 만약 상속받은 클래스가 있다면 따로 설정을 하지 않았다면 보이지 않거나, 보이더라도 깔끔하지 않다. 아래와 같이 코드로 확인해 보자.

 


@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class ParentDTO { // 부모 클래스

    private String data3;
}

@Getter
@ToString(callSuper = true)
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class HelloDTO extends ParentDTO{ // 자식 클래스

    private String data1;
    private Integer data2;
}

HelloDTO helloDTO = HelloDTO.builder().data1("hello").data2(100).data3("parent").build();
System.out.println("helloDTO = " + helloDTO);

 

위처럼 helloDTO 를 출력하면 아래와 같이 출력된다.

 

helloDTO = HelloDTO(super=ParentDTO(data3=parent), data1=hello, data2=100)

 

data3 필드가 보이는 것도 @ToString(callSuper = true) 이 설정을 추가해서 보이는 것이지 만약 하지 않았다면 보이지 않았을 것이다.

 

이때 ObjectMapper 를 사용해 객체를 json 으로 변경하여 로깅을 하면 보기에도 깔끔하고 모든 값을 다 볼 수 있다.

 

ObjectMapper objectMapper = new ObjectMapper();
System.out.println(objectMapper.writeValueAsString(helloDTO));

// 출력 결과 : {"data3":"parent","data1":"hello","data2":100}

 

Json 을 쉽게 다룰 수 있는 또다른 라이브러리로 JsonPath 가 있는데, 이번 시간에는 Json 을 쉽게 다룰 수 있는 ObjectMapper, JsonPath 에 대해 알아보는 시간을 갖도록 하겠다.

 


▶ ObejctMapper

▷ 사용법

아래와 같이  jackson-databind  라이브러리이지만 기본적으로  spring-boot-starter-web  에 들어있기 때문에 spring-boot-starter-web 을 쓰고 있다면 따로 추가하지 않아도 된다.

 

implementation 'com.fasterxml.jackson.core:jackson-databind' // 이지만

implementation 'org.springframework.boot:spring-boot-starter-web' // 에 있음

 

개념

ObjectMapper 에 대해 간단하게 개념을 짚고 넘어가자.

  • 직렬화
    •  객체 → JSON 
    • 자바 시스템 내부에서 사용되는 Object 또는 Data를 외부의 자바 시스템에서도 사용할 수 있도록 byte 형태로 데이터를 변환하는 기술
    • ObjectMapper 는 리플렉션을 활용해서 직렬화
    • @ResponseBody, @RestController, @ReseponseEntity 에서 사용되고, 이 때 writeValueAsString() 이라는 메서드가 사용됨
String jsonString = mapper.writeValueAsString(myDTO());

 

  • 역직렬화
    •  JSON → 객체 
    • ObjectMapper 는 리플렉션을 활용해서 역직렬화
    • @RequestBody 에서 사용됨
    • 역직렬화 과정
      1. 기본 생성자로 객체 생성
      2. 필드값을 찾아서 값을 바인딩

유용 메서드

  •  writeValueAsString() 
    객체를 받아 String 으로 반환 (= 직렬화)
  •  readValue() 
    String 을 받아 원하는 객체로 반환 (=역직렬화)
  •  convertValue() 
    객체를 받아 원하는 객체로 반환

Jayway JsonPath

개요

아래와 같이 dependency 를 추가하면 사용할 수 있다.

 


implementation 'com.jayway.jsonpath:json-path'

 

Jayway JsonPath는 Stefan Goessner의 JsonPath 구현을 자바로 포팅한 라이브러리이다.

XML의 가장 큰 장점은 XPath(XML Path Language)로 XML 문서에서 원하는 부분을 바로 추출할 수 있다는 점인데, 즉 Java 에서 JSON 을 쉽게 다루기 위한 라이브러리라고 생각하면 된다.

 

<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
    <book>
        <title lang="en">Harry Potter</title>
        <price>29.99</price>
    </book>
    <book>
        <title lang="en">Learning XML</title>
        <price>39.95</price>
    </book>
</bookstore>

 

위 XML 예제에서 bookstore의 첫 번째 책 요소를 추출하는 XPath 표현은 아래와 같다.

  • _bookstore_book[1] : 첫 번째 책 요소를 추출
  • _bookstore_book[last()] : 여러 책중 맨 마지막 책을 추출

Jayway JsonPath 사용법

  • JsonPath 표기법
    1. dot 표현식
      $.store.book[0].title
    2. bracket 표현식
      $[’store’][‘book’][0][’title’]
  • 대표적인 연산자
연산자 설명
$ 루트 노드로 모든 Path 표현식은 이 기호로 시작된다.
@ 처리되고 있는 현재 노드를 나타내고 필터 조건자에서 사용된다.
* 와일드카드로 모든 요소와 매칭이 된다
. Dot 표현식의 자식노드
[start:end] 배열 slice 연산자
[?(<expression>)] 필터 표현식으로 필터 조건자가 참인 경우에 매칭되는 모든 요소를 만을 처리한다 ex. book[?(@.price == 49.99)]

 

  • 데이터 추출
    •  parse() 
      여러 입력 타입(ex. String, InputStream, File)에 따라 JSON을 읽어 들인다.
      인자로는 json 타입, 반환 결과는 DocumetContext
    •  DocumetContext 
      ReadContext와 WriteContext를 상속받은 인터페이스로, JsonContext가 구현체이다.
    • JsonContext
      •  read()  : jsonPath를 받아서 지정된 형식으로 리턴
      •  renameKey()  : key 이름 변경
      •  set()  : value 변경
      •  add()  : 추가
      •  put()  : 변경
      •  delete()  : 삭제
      •  json()  : Object로 변환
      •  jsonString()  : String 으로 변환

 

이번 시간에는 json 을 쉽게 다룰 수 있는 2가지 라이브러리에 대해 알아보았는데, 로깅이나 값 추출, 파싱 시에 유용하게 쓰일 수 있으니 참고하면 도움이 될 것이다.