개요
Spring Boot(또는 Spring 4 MVC)는 HTTP 요청-응답시 application/json;charset=UTF-8
형식의 메시지에 대해 JSON 문자열-Java 오브젝트를 자동으로 상호 변환해준다. 이 기능을 입맛에 맞게 잘 사용하려면 동작의 상세 원리를 이해하는 것이 필수이다.
먼저 읽어볼만한 글
POJO-JSON 상호 변환의 상세
MappingJackson2HttpMessageConverter
클래스가 Spring Boot 초기 구동시JacksonHttpMessageConvertersConfiguration
클래스에 의해 싱글턴 빈으로 등록되어 POJO-JSON간의 상호 변환을 수행한다.MappingJackson2HttpMessageConverter
는 이름에서 보여지듯이 Java 진영에서 널리 쓰이는 JSON 라이브러리인 Jackson(Spring Boot 1.3.5 기준 Jackson 2.6 내장)을 사용하여 메시지를 상호 변환한다.MappingJackson2HttpMessageConverter
는HttpMessageConverter
인터페이스의 구현체로 read(), write() 메써드를 이용하여 JSON을 처리한다. 내부적으로는 Jackson이 제공하는ObjectMapper
클래스를 사용하는데 커스텀 설정을 적용하여 미리 빈으로 등록해두면 변환시 자동으로 해당 빈을 대신 사용한다.
ObjectMapper 커스터마이징
현재 시간을 JSON을 반환하는 간단한 기능의 컨트롤러 클래스를 아래와 같이 작성해보자.
package com.jsonobject.example;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import java.time.LocalDateTime;
@Controller
@RequestMapping(value = "/now")
public class JsonController {
@RequestMapping(method = RequestMethod.GET)
public ResponseEntity<?> now() {
return new ResponseEntity<LocalDateTime>(LocalDateTime.now(), HttpStatus.OK);
}
}
위 기능을 요청하면 아래와 같이 응답한다.
{
"hour": 2,
"minute": 7,
"nano": 468000000,
"second": 1,
"dayOfMonth": 11,
"dayOfWeek": "SATURDAY",
"dayOfYear": 163,
"month": "JUNE",
"monthValue": 6,
"year": 2016,
"chronology": {
"id": "ISO",
"calendarType": "iso8601"
}
}
위는 Java 8이 제공하는 LocalDateTime
오브젝트가 JSON으로 변환되어 출력된 결과이다. 클라이언트에게 보여주기에는 지나치게 친절하면서 장황한 데이터 출력이다. 최근 REST API의 추세는 날짜/시간을 ISO-8601 형식으로 응답하는 것이다. ObjectMapper
오브젝트의 커스터마이징 빈 등록으로 이를 해결할 수 있다.
/build.gradle의 의존성에 아래 라이브러리를 추가한다.
dependencies {
compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.7.4'
}
- Jackson Datatype JSR310은
LocalDateTime
을 비롯한 Java 8의 날짜/시간 관련 오브젝트를 인식할 수 있는 Jackson 라이브러리의 추가 모듈이다.
커스터마이징된 빈을 등록하기 위한 @Configuration
클래스를 아래와 같이 작성한다.
package com.jsonobject.example;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
@Configuration
public class JsonConfig {
@Bean
public ObjectMapper objectMapper() {
return Jackson2ObjectMapperBuilder.json().featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS).modules(new JavaTimeModule()).build();
}
}
동일한 요청을 다시 해보자. 전과 다르게 아래와 같이 ISO-8601 형식으로 출력되는 것을 확인할 수 있다.
"2016-06-11T03:57:47.146"
참고 글
출처: http://jsonobject.tistory.com/235 [지단로보트의 블로그]
'SPRINGBOOT > 소스코드' 카테고리의 다른 글
Spring Boot 프로젝트에서 Profile 적용하기 (0) | 2017.10.26 |
---|---|
Spring Boot, Multipart 파일 업로드 구현하기 (0) | 2017.10.26 |
Spring Boot, JUnit을 이용한 유닛 테스트 구현하기 (0) | 2017.10.26 |
Spring Boot, @Async 비동기 실행 로직 구현하기 (0) | 2017.10.26 |
Spring Boot, 작업 스케쥴러 데몬 구현하기 (0) | 2017.10.26 |
Spring, RestTemplate으로 REST 클라이언트 구현하기 (0) | 2017.10.26 |
Spring Boot, Logback을 이용한 로그 출력하기 (0) | 2017.10.26 |
Spring, HandlerInterceptor(인터셉터) 구현하기 (0) | 2017.10.26 |