틀린 내용이 있다면 댓글이나 robin00q@naver.com으로 보내주시면 반영하겠습니다,, ^^
www.baeldung.com/jackson-annotations
Jackson Annotation Examples | Baeldung
The core of Jackson is basically a set of annotations - make sure you understand these well.
www.baeldung.com
을 참고하고, 정리했습니다,,^^
github.com/robin00q/jackson_practice
robin00q/jackson_practice
Contribute to robin00q/jackson_practice development by creating an account on GitHub.
github.com
모든 코드는 위의 링크에 저장되어있습니다. (IntelliJ의 Springinitializer / spring-boot-starter-web / lombok / java 11 을 사용했습니다)
- ObjectMapper은 자동으로 의존성 주입되므로 따로 설정할 필요가 없습니다.
- 테스트 할 때 @SpringBootTest를 선언하거나 new ObjectMapper()를 사용하여 ObjectMapper를 사용하면 됩니다.
Jackson Deserialization(Json 데이터를 Java 객체로 변환) Annotation
1. @JsonCreator
- Json 데이터를 Java 객체로 받고 싶은 경우 사용합니다.
- Constructor(생성자) 위에 Annotation을 추가하여 사용합니다.
- 파라미터에 @JsonProperty를 사용하여 json key값을 명시합니다.
- json key값과 Java 객체의 프로퍼티가 같다면 생략 가능합니다.
예시 - 아래의 데이터를 @JsonCreator을 사용하여 Java 객체에 담아보자
{
"id": 1,
"name": "My bean"
}
정답 / 테스트
@Getter
@ToString
public class JsonCreatorDTO {
private Integer id;
private String name;
@JsonCreator
public JsonCreatorDTO(@JsonProperty("id") Integer id, @JsonProperty("name") String name) {
this.id = id;
this.name = name;
}
}
@Test
void test() throws JsonProcessingException {
// given
String json = "{\"id\":1,\"name\":\"My bean\"}";
// when
JsonCreatorDTO jsonCreatorDTO = new ObjectMapper()
.readerFor(JsonCreatorDTO.class)
.readValue(json);
// then
assertEquals(jsonCreatorDTO.getId(), 1);
assertEquals(jsonCreatorDTO.getName(), "My bean");
System.out.println(jsonCreatorDTO);
}
2. @JacksonInject
- Json 데이터에서 데이터를 가져오지 않고 injection을 받아 Java 데이터를 채웁니다.
예시 - 아래의 Json Data에 Id 프로퍼티를 Injection받아 Java 객체의 데이터를 채워보자
{
"name": "My bean"
}
JacksonInjectDTO(id=1, name=My bean)
정답 / 테스트
@Getter
@ToString
public class JacksonInjectDTO {
@JacksonInject
private Integer id;
private String name;
}
@Test
void test() throws JsonProcessingException {
// given
String json = "{\"name\":\"My bean\"}";
// when
InjectableValues inject = new InjectableValues.Std()
.addValue(Integer.class, 1);
JacksonInjectDTO jacksonInjectDTO = new ObjectMapper().reader(inject)
.forType(JacksonInjectDTO.class)
.readValue(json);
// then
assertEquals(jacksonInjectDTO.getId(), 1);
assertEquals(jacksonInjectDTO.getName(), "My bean");
System.out.println(jacksonInjectDTO);
}
3. @JsonAnySetter
- Map객체를 사용할 경우 유용하게 사용할 수 있습니다.
- Map객체에 데이터를 추가하는 메소드 위에 @JsonAnySetter를 추가합니다.
예시 - 아래의 데이터를 @JsonAnySetter를 사용하여 attr1, attr2를 추가해보자
{
"name": "My bean",
"attr2": "val2",
"attr1": "val1"
}
정답 / 테스트
@Getter
@ToString
public class JsonAnySetterDTO {
private String name;
private Map<String, String> properties = new HashMap<>();
@JsonAnySetter
public void addProperties(String key, String value) {
properties.put(key, value);
}
}
@Test
void test() throws JsonProcessingException {
// given
String json = "{\"name\":\"My bean\",\"attr2\":\"val2\",\"attr1\":\"val1\"}";
// when
JsonAnySetterDTO jsonAnySetterDTO = new ObjectMapper().readerFor(JsonAnySetterDTO.class)
.readValue(json);
// then
assertEquals(jsonAnySetterDTO.getProperties().get("attr1"), "val1");
assertEquals(jsonAnySetterDTO.getProperties().get("attr2"), "val2");
System.out.println(jsonAnySetterDTO);
}
4. @JsonSetter
- @JsonProperty대신 Setter 메소드 위에 사용합니다.
- 프로퍼티와 Json Key값이 다른 경우 @JsonProperty("Json Key 값") 으로 사용합니다.
예시 - 아래의 데이터를 @JsonSetter를 사용하여 받아보자
{
"id": 1,
"name": "My bean"
}
정답 / 테스트
@Getter
@ToString
public class JsonSetterDTO {
private Integer id;
private String name;
@JsonSetter("id")
public void setId(Integer id) {
this.id = id;
}
@JsonSetter("name")
public void setName(String name) {
this.name = name;
}
}
@Test
void test() throws JsonProcessingException {
// given
String json = "{\"id\":1,\"name\":\"My bean\"}";
// when
JsonSetterDTO jsonSetterDTO = new ObjectMapper().readerFor(JsonSetterDTO.class)
.readValue(json);
// then
assertEquals(jsonSetterDTO.getId(), 1);
assertEquals(jsonSetterDTO.getName(), "My bean");
System.out.println(jsonSetterDTO);
}
5. @JsonDeserialize
- custom한 deserierizer을 선언하여 역직렬화를 할 수 있습니다.
- 메소드 위에 @JsonDeserialize(using = "내가 정의한 deserializer") 로 사용합니다.
예시 - 아래의 Json을 @JsonDeserialize를 이용하여 Java Object로 가져와라 [LocalDateTime 사용]
{
"name": "party",
"eventDate": "2020-10-18 11:11:11"
}
정답 + deserializer / 테스트
@Getter
@ToString
public class JsonDeserializeDTO {
private String name;
@JsonDeserialize(using = CustomJsonDeserializer.class)
private LocalDateTime eventDate;
}
public class CustomJsonDeserializer extends StdDeserializer<LocalDateTime> {
public static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
public CustomJsonDeserializer() {
this(null);
}
protected CustomJsonDeserializer(Class<?> vc) {
super(vc);
}
@Override
public LocalDateTime deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException, JsonProcessingException {
String date = jsonParser.getText();
return LocalDateTime.parse(date, formatter);
}
}
@Test
void test() throws JsonProcessingException {
// given
String json
= "{\"name\":\"party\",\"eventDate\":\"2020-10-18 11:11:11\"}";
// when
JsonDeserializeDTO jsonDeserializeDTO = new ObjectMapper().readerFor(JsonDeserializeDTO.class)
.readValue(json);
// then
assertEquals(jsonDeserializeDTO.getName(), "party");
assertEquals(jsonDeserializeDTO.getEventDate(), LocalDateTime.parse("2020-10-18 11:11:11", CustomJsonDeserializer.formatter));
System.out.println(jsonDeserializeDTO);
}
6. @JsonAlias
- 여러개의 Json Key를 하나의 Java 변수가 받을 수 있도록 설정할 수 있습니다.
- @JsonAlias({"key1, "key2", ..}) 으로 변수위에 선언할 수 있습니다.
예시 - fName / f_name 을 모두 받을 수 있는 Java 객체를 @JsonAlias를 이용해 만드시오
{
"fName": "John",
"lastName": "Green"
}
----
{
"f_name": "John",
"lastName": "Green"
}
정답 / 테스트
@Getter
@ToString
public class JsonAliasDTO {
@JsonAlias({"f_name", "fName"})
private String firstName;
private String lastName;
}
@Test
void test() throws JsonProcessingException {
// given
String json = "{\"f_name\": \"John\", \"lastName\": \"Green\"}";
// String json = "{\"fName\": \"John\", \"lastName\": \"Green\"}";
System.out.println(json);
// when
JsonAliasDTO jsonAliasDTO = new ObjectMapper().readerFor(JsonAliasDTO.class)
.readValue(json);
// then
assertEquals(jsonAliasDTO.getFirstName(), "John");
assertEquals(jsonAliasDTO.getLastName(), "Green");
System.out.println(jsonAliasDTO);
}
'Jackson' 카테고리의 다른 글
Jackson Serialization Annotation (1) | 2020.10.17 |
---|