이번 시간엔 Java의 Jackson json library 중 @JsonSetter
라는 annotation을 어떻게 사용해야 할지 알아보겠다.
public class Person {
private String name;
private Integer age = -1;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
@JsonSetter(value = "age", nulls = Nulls.SKIP)
public void setAge(Integer age) {
this.age = age + 10;
}
}
위와 같이 Person
클래스를 정의해보자. 필드는 간단하게 name
과 age
두개로 구성되어 있다. 사실 있는 값을 그대로 받아온다면 굳이 @JsonSetter
는 사용할 필요가 없다. 하지만 만약 우리가 값에 어떤 특정 조작을 해야 한다면, 저 annotation은 매우 유용하다고 할 수 있다. 위의 경우엔 입력된 나이 값에 10을 더해서 값을 세팅하도록 해놨다.
여기서 신경써야할 몇가지 코너 케이스들이 있다.
- Input json에 age 필드가 없을 경우
- 이 경우엔 기본적으로 annotate되어있는 이 함수가 실행되지 않는다. 그래서 위에서
age=-1
로 기본 값을 설정해 놓은 것이다.
- 이 경우엔 기본적으로 annotate되어있는 이 함수가 실행되지 않는다. 그래서 위에서
- age==null인 경우
- 이 경우는 별도의 지시가 없으면 함수가 실행이 된다. 그런데 대부분의 경우 null이나 필드가 없는 경우나 동일시하는게 맞기 때문에, 이번 예제에서는
nulls=Nulls.SKIP
을 사용함으로써, 값이 null일때는 함수를 실행하지 않도록 하였다. 그럼 결국 기본값인 -1을 유지할 것이다.
- 이 경우는 별도의 지시가 없으면 함수가 실행이 된다. 그런데 대부분의 경우 null이나 필드가 없는 경우나 동일시하는게 맞기 때문에, 이번 예제에서는
마지막으로 unit test를 써서 잘 동작하는지 확인해보자.
@Test
public void testDeserialization() throws IOException {
String jsonStr = "{\n"
+ " \"name\": \"Jacob\",\n"
+ " \"age\": null\n"
+ "}";
ObjectMapper mapper = new ObjectMapper();
Person person = mapper.readValue(jsonStr, Person.class);
assertEquals("Jacob", person.getName());
assertEquals(-1L, person.getAge().longValue());
jsonStr = "{\n"
+ " \"name\": \"Jacob\",\n"
+ " \"age\": 30\n"
+ "}";
person = mapper.readValue(jsonStr, Person.class);
assertEquals(40L, person.getAge().longValue());
}