Why Spring deprecate MediaType.APPLICATION_JSON_UTF8

에러 출현

스프링 테스트 코드를 짜기 위해 Junit 5 + Mockito를 사용해 개발하던 중 발생한 에러였습니다.

회사 코드인 관계로 코드를 올릴 수는 없어서 예제 코드로 대체합니다.

@Test
fun apiTest(){
    mockMVC.perform(
        post("api/test")
        .contentType(MediaType.APPLICATION_JSON)
        .content("Test")
    )
}

위 테스트코드는 api/test로 post 요청을 보내는 테스트 코드입니다.

이 때 응답으로는 List<Foo>를 받게 됩니다.

이 Foo 객체 내부에 선언된 프로퍼티의 값 중 한글이 있었습니다.

문제는 응답 바디에 포함된 한글이 깨지는 이슈가 있었습니다.

원인은 무엇이냐

MockMVCResponse를 잘 살펴보면 응답 헤더의 ContentType이 application/json인 것을 확인할 수 있었습니다.

이것이 문제되는 이유는 charset=utf-8이 포함되어있지 않기 때문인데요.

이러한 인코딩 처리가 헤더에 포함되지 않으면 한글이 깨질 수 밖에 없습니다.

request의 경우 application/json;charset=utf-8이 헤더에 포함되기 때문에 요청은 한글이 잘 나오지만, response의 경우 그렇지 않았습니다.

이것이 문제의 원인이었습니다.

그건 그렇고 MediaType.APPLICATION_JSON_UTF8은 왜 depreacted?

스크린샷 2020-06-18 오후 11 44 05

그렇게 문제의 원인은 찾았으나 발생했는지 이유를 몰라 끙끙대던 중 한 가지 의문이 들었습니다.

contentType을 설정할 때 왜 MediaType.APPLICATION_JSON_UTF8이 아닌 MediaType.APPLICATION_JSON을 보내는지 궁금해졌습니다.

MediaType.APPLICATION_JSON_UTF8depreacted된 이유는 스프링 2.2.0 업데이트와 관련이 있습니다.

deprecated가 사실은 이번 문제의 핵심이었습니다.

스프링 부트의 경우 2.2.0부터 application/json;charset=UTF-8 요청에 대해서 charset=utf-8이 빠지게 되었습니다.

스프링 부트 2.2.0 부터는 utf-8 인코딩 처리를 별도로 해주지 않게 변경되었기 때문에 APPLICATION_JSON_UTF8도 자연히 deprecated된 것이지요.

그래서 utf-8 인코딩에 대한 처리를 별도로 해줘야 했습니다.

한글이 깨지는 원인도 스프링 부트 2.2.0 부터 charset=utf-8이 deprecated 되었기 때문이었습니다.

인코딩 처리를 하는 방법은 여러 방법이 있을 수 있는데 메시지 컨버터에 추가하는 방법도 있으며 (아래 레퍼런스 참조) 저희 팀의 경우 필터에 utf-8을 추가하여 이 문제를 해결하였습니다.

그럼 스프링은 왜 응답에 charset=utf-8을 없앴나?

스크린샷 2020-06-19 오전 12 17 29

이 원인은 크롬 브라우저와 같이 주요 브라우저들이 사양을 준수하고 charset=UTF-8로 인코딩되는 특수한 문자들을 올바르게 해석해주므로 정확히는 스프링 5.2부터, 스프링 부트의 경우 2.2.0부터 응답에 이를 포함시키지 않게 되었습니다.

Reference

http://honeymon.io/tech/2019/10/23/spring-deprecated-media-type.html



© 2022. by minkuk

Powered by minkuk