Object Mapper

Object Mapper

Object Mapper를 통하여 Java에서 JSON 값을 가공 및 활용할 수 있습니다.

Java Object를 JSON으로 Serializing 하거나 반대로 JSON 객체를 Object로 Deserializing 할 수 있습니다.

Dependency

저는 GradleJackson Databind 2.12.3 API를 사용하였습니다.

maven repository 홈페이지에서 object mapper키워드를 검색해서 찾을 수 있습니다.

편의를 위해 아래 코드 블럭에 위 버전의 dependency를 복사해두었습니다.

다른 버전 이용은 아래 링크를 참고해주세요

MVN REPOSITORY - jackson databind

1
2
// https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.12.3'

build.gradle에 dependency를 추가하면 jar파일을 온라인에서 불러와 클래스 패스에 자체적으로 추가시켜줍니다.

Using Case

User 객체가 내부적으로 Car 객체의 배열을 갖는 형태로 구성하였습니다.

이해를 돕기 위해 아래 사진을 첨부하였습니다.

img.png

User 클래스 멤버 변수

  • String name
  • int age
  • List cars

Car 클래스 멤버 변수

  • String name
  • String carNumber
  • String type
User 객체 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package dto;

import java.util.List;

public class User {
private String name;
private int age;
private List<Car> cars;

public List<Car> getCars() {
return cars;
}

public void setCars(List<Car> cars) {
this.cars = cars;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", cars=" + cars +
'}';
}
}
Car 객체 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package dto;

import com.fasterxml.jackson.annotation.JsonProperty;

public class Car {
private String name;

private String carNumber;

private String type;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getCarNumber() {
return carNumber;
}

public void setCarNumber(String car_number) {
this.carNumber = car_number;
}

public String getType() {
return type;
}

public void setType(String type) {
this.type = type;
}

@Override
public String toString() {
return "Car{" +
"name='" + name + '\'' +
", car_number='" + carNumber + '\'' +
", type='" + type + '\'' +
'}';
}
}

0. 객체 준비

  1. User 객체에 나이와 이름을 setter를 통해 입력해줍니다.

  2. car 객체 2개를 생성하여 이름, 차량 번호, type을 입력해줍니다.

    • User 객체에 보유한 차들을 List 형태로 가지고 있기 때문에 2개를 생성하였습니다.
  3. 생성한 car 객체 2개를 Array 형태로 변환하여 User 객체에 넣어줍니다.

객체 생성 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var user = new User();
user.setName("홍길동");
user.setAge(10);

var car1 = new Car();
car1.setName("K5");
car1.setCarNumber("11가 1111");
car1.setType("sedan");

var car2 = new Car();
car2.setName("Q5");
car2.setCarNumber("22가 2222");
car2.setType("SUV");

List<Car> carList = Arrays.asList(car1,car2);
user.setCars(carList);

1. Object를 JSON 등의 타입으로 변환

  1. ObjectMapper 객체를 생성해줍니다.
  2. writeValueAsString()메서드를 통하여 객체를 String으로 변환하고 String 변수에 담아줍니다.
    • User 객체를 JSON 형태로 설계하였기 때문에 JSON 형태의 String이 출력됩니다.
    • 객체의 Value를 String으로 저장한다라고 해석하시면 이해하기 편합니다.

img.png

Object Mapper 코드
1
2
3
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(user);
System.out.println(json);
1
2
// 결과값
// {"name":"홍길동","age":10,"cars":[{"name":"K5","carNumber":"11가 1111","type":"sedan"},{"name":"Q5","carNumber":"22가 2222","type":"SUV"}]}

1-1. JSON 특정 key의 value 조회

readTree() 메서드

JSON의 가장 바깥부분의 key들은 JsonNode를 가지고 있어, 이를 통해 JSON 객체에 직접적인 접근을 할 수 있습니다.

JSON은 트리 구조와 같이 생겨서 Node를 읽어올 때는 readTree(객체) 메서드를 사용합니다.

JsonNode 코드 확인하기
1
2
3
4
5
6
JsonNode jsonNode = objectMapper.readTree(json);
String _name = jsonNode.get("name").asText();
int _age = jsonNode.get("age").asInt();

System.out.println("name : " + _name);
System.out.println("age : " + _age);
1
2
3
// 결과값
// name : 홍길동
// age : 10

하지만, 일반적인 key, value 쌍과는 다르게 cars는 내부적으로 배열 형태를 띄고 있습니다.
내부의 배열은 ArrayNode라는 타입을 이용하여 접근할 수 있습니다.

순서

  1. JsonNode로 cars 배열의 Node 불러오기
  2. JsonNode를 ArrayNode로 명시적 형변환
ArrayNode 코드 확인하기
1
2
3
JsonNode _cars = jsonNode.get("cars");
ArrayNode arrayNode = (ArrayNode)_cars;
System.out.println("cars : " + arrayNode);
1
2
// 결과값
// cars : [{"name":"K5","carNumber":"11가 1111","type":"sedan"},{"name":"Q5","carNumber":"22가 2222","type":"SUV"}]

1-2. JSON 특정 key의 value 변경

JsonNode는 value를 변경할 수 없도록 되어 있습니다.

따라서 값을 변경하고 싶을 때는 JsonNode를 ObjectNode로 명시적 형변환 해준 뒤에 값을 변경할 수 있습니다.

예제 코드 확인하기
1
2
ObjectNode objectNode = (ObjectNode) jsonNode;
objectNode.put("name", "정동렬");

추가 적으로 objectNode의 값을 보기 편하게 출력하려면 toPrettyString()메서드를 사용하면 됩니다.

  • System.out.println(objectNode.toPrettyString());

2. JSON을 Object로 변환

바로 위 ArrayNode 코드 확인하기에서 cars의 값을 arrayNode에 초기화시켜주었습니다.

이번에는 역으로 JSON 형태로 존재하는 arrayNode를 기존 User객체에 넣어주었던 List 객체로 mapping 해보겠습니다.

convertValue(Object fromValue, TypeReference toValueTypeRef)

  • fromValue : 변환하고 싶은 객체 (JSON형태의 값)
  • TypeReference : mapping하고 싶은 객체의 타입 (List)
Object로 mapping하기
1
2
List<Car> cars = objectMapper.convertValue(arrayNode, new TypeReference<List<Car>>() {});
System.out.println(cars);
1
2
// 결과값
// [Car{name='K5', car_number='11가 1111', type='sedan'}, Car{name='Q5', car_number='22가 2222', type='SUV'}]
Author

Inwoo Jeong

Posted on

2021-10-07

Updated on

2021-10-07

Licensed under

You need to set install_url to use ShareThis. Please set it in _config.yml.

댓글