지난 시간에 ObjectMapper 에 대해 설명했다.
[Java] 리플렉션, ObjectMapper
https://starsufers.tistory.com/40
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 에서 사용됨
- 역직렬화 과정
- 기본 생성자로 객체 생성
- 필드값을 찾아서 값을 바인딩
▷ 유용 메서드
- writeValueAsString()
객체를 받아 String 으로 반환 (= 직렬화) - readValue()
String 을 받아 원하는 객체로 반환 (=역직렬화) - convertValue()
객체를 받아 원하는 객체로 반환
▶ Jayway JsonPath
▷ 개요
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 표기법
- dot 표현식
$.store.book[0].title - bracket 표현식
$[’store’][‘book’][0][’title’]
- dot 표현식
- 대표적인 연산자
연산자 | 설명 |
$ | 루트 노드로 모든 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 으로 변환
- parse()
이번 시간에는 json 을 쉽게 다룰 수 있는 2가지 라이브러리에 대해 알아보았는데, 로깅이나 값 추출, 파싱 시에 유용하게 쓰일 수 있으니 참고하면 도움이 될 것이다.
'별밤 일지 > 개발' 카테고리의 다른 글
[Flutter] 우리는 언제 GestureDetector가 필요할까? (2) | 2024.09.23 |
---|---|
[Flutter] macOS에서 vscode로 flutter 개발환경 구축하기 (0) | 2024.06.10 |
[Flutter] Retrofit 적용 (0) | 2024.04.16 |
[Java] 리플렉션, ObjectMapper (2) | 2024.03.12 |
[Springboot] Test With Mockito, JUnit (4) | 2024.03.05 |