특히 java 8의 date 객체들을 쓰게 되면 더더욱 그렇다.
응답 처리
java 8의 LocalDateTime이나 LocalDate를 사용하면 응답하는 MappingJackson2JsonView의 기본 json 결과는 다음과 같다.
{ "localDateSample" : [2016,7,8], "localDateTimeSample" : [2016,7,1,0,0] }
serialized as numeric timestamps 형태로 년월일 / 년월일시분 값을 넘겨주는데 이런 형태로 응답하면 client의 javascript 객체에서 변환해서 쓸 때 불편한 점이 많다.
date format string 을 넘겨받아 사용하는게 더 사용하기 편하다고 생각을 해서 다음과 같이 boot properties 설정을 한다.
# response datetime 처리 설정
spring.jackson.serialization.write-dates-as-timestamps=false
위와 같이 설정을 하면 응답처리는 다음과 같이 된다.
{ "localDateSample" : "2016-07-08", "localDateTimeSample" : "2016-07-31T00:00" }
이렇게 사용하면 javascript에서 사용하기가 편해지고 timezone 설정이 들어간 경우도 moment.js 와 같은 라이브러리를 사용하면 쉽게 사용할 수 있다.
요청 처리
위와 같이 설정하는 경우 응답에 대해서 처리는 되었지만 요청이 온 경우에 대해서도 처리를 해주어야 한다.
요청에 대해 date format string 을 넘겨받는 설정은 WebMvcConfigurerAdapter에 다음과 같이 선언을 해준다.
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
...
// request date conversion 처리
@Override
public void addFormatters(FormatterRegistry registry) {
DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();
registrar.setUseIsoFormat(true);
registrar.registerFormatters(registry);
}
}
여기까지 설정을 하면 @ResponseBody로 리턴되는 produces = MediaType.APPLICATION_JSON_VALUE 응답처리에 올바르게 적용된다.
하지만 html, json에 대한 contentNegotiation 처리에도 올바른 응답을 처리하기 위해선 WebMvcConfigurerAdapter에 다음과 같이 선언해야한다.
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
...
@Autowired
private ObjectMapper objectMapper;
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.viewResolver(thymeleafViewResolver); // thymeleaf를 쓰는 경우
registry.enableContentNegotiation(new MappingJackson2JsonView(objectMapper));
}
}
위에서 중요한 핵심은 objectMapper를 spring boot에서 생성한 것을 써야한다는 점이다. 만약 new MappingJackson2JsonView() 로 생성한다면 spring boot 설정으로 선언한 objectMapper가 아닌 spring web의 Jackson2ObjectMapperBuilder로 생성한 objectMapper를 사용하기 때문에 jackson 설정이 동작하지 않는다.
댓글 없음:
댓글 쓰기