
순조롭게 프로젝트를 진행하던 중, postman 에서 응답을 받는데 한글이 아닌 ???를 받았다. 이게 뭔가… 일단 encoding 문제인 것 같아 차근차근 문제를 해결해보기로 한다. 이 문제를 해결하기 위해 여러 방법들을 찾아보았고 그 순서에 따라 글을 작성했다.
postman 페이지 자체에서 문제가 있나싶어 command + , 명령어를 통해 incoding 설정을 찾아보려 했으나 따로 그런것은 없었다. 즉, 서버에서 오가면서 charset을 어떤 것으로 설정하느냐의 문제였고, 위 오류를 제외하고 다른 요청 응답에서는 한글이 잘만 출력되는 것을 확인했다.
postman 자체에는 문제가 없는 것을 확인했다.
그렇다면, 현재 Spring을 통해 개발하고 있는 intelliJ에 문제가 생긴 것은 아닌가? 라는 생각과 함께
command + , 명령어로 intelliJ 설정에 들어갔다. 마찬가지로 딱히 그런 설정은 없었다. 그래서 헤더에 application/json;charset=UTF-8 을 넣어준다면 정상적으로 출력되지 않을까? 하여 controller에 @GetMapping(value = "/categories", produces = "application/json;charset=UTF-8") 이렇게 입력하여 인코딩에서 문제가 생기지 않도록 설정했지만, 결과는 ???로 동일했다.
그렇다면, 어떻게 해결할 수 있을까 싶은 생각이 들었을 때, WebMvcConfigurer 를 구현하는 어떤 설정자를 만들어 컨트롤러에서 전송하는 모든 응답 데이터의 인코딩이 UTF-8로 인코딩된다는 사실을 알게되었다. 바로 도전해본다.
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.defaultContentType(MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN)
.mediaType("json", MediaType.APPLICATION_JSON)
.mediaType("text", MediaType.TEXT_PLAIN)
.parameterName("mediaType")
.favorPathExtension(true);
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new StringHttpMessageConverter(StandardCharsets.UTF_8));
converters.add(new MappingJackson2HttpMessageConverter());
}
}
WebMvcConfig를 만들어서 모든 요청이 UTF-8로 인코딩되는 코드이다. 하지만, 이렇게 설정해도 값이 변하지 않는다는 것을 깨달았다. 대체.. 어떻게 ㅠ
찾았다. 생각보다 이유는 간단했다. 나는 정적인 파일들을 임의로 DB에 저장하기 위해 application.properties 에 한글로 모든 파일명을 저장해놓았고, 이를 불러오면서 split을 통해 String[] 에 담아 각 파일명을 이용했다. 혹시라는 생각에 나는 이 Spring[] 을 출력해보았고 그 결과는 ???인 것을 확인했다.
결국, 파일 encoding 문제였다.
문제를 찾았으니 금방 해결되겠지 생각했다. 이 생각이 오만이였다는 것을 알아채기까지는 그리 오래 걸리지 않았다.application.properties 파일을 utf-8로 인코딩하기 위해
@PropertySource(value = "classpath:application.properties", encoding = "UTF-8")
위 코드를 사용하였고, 이는 파일을 지정한 형식으로 encoding 하여 가져올 수 있다는 뜻이다. 하지만 이게 왠걸. 이래도 물음표 살인마는 굳건했다.
SpringBoot 에서 properties를 읽을 수 있는 PropertySourceLoader
를 구현하고 있는 PropertiesPropertySourceLoader 클래스를 알아보았다.

PropertiesPropertySourceLoader 클래스 내부에서는 OriginTrackedPropertiesLoader 의 load() 메서드를 호출한다.

위에서 볼 수 있듯이 OriginTrackedPropertiesLoader 내부에서 사용하는 CharacterReader 클래스는 인코딩을 StandardCharsets.ISO_8859_1로 하고 있다. yml 의 기본 인코딩은 StandardCharsets.UTF_8 이지만, properties는 ISO_8859_1이기 때문에 그동안 많은 짓을 해도. 변경되지 않고 물음표 살인마와 마주쳤던 것이다.
이제 이를 해결하기 위해 우리는 단 한가지의 설정을 해주면 된다(ㅠㅠ).

위의 Transparent native-to-ascii conversion 을 체크해준다면 properties 인코딩 설정을 변경할 수 있게 된다. 이제는 우리가 기존에 짰던 코드에서 인코딩을 UTF-8 로 변경하고자 했던 노력들이 성공할 수 있게 된다.
이로써 값은 완벽하게. 한글로 나오기 시작했다. 시간은 오래걸렸지만, 인코딩에 대해 깊게 생각해볼 수 있는 시간이였던 것 같다.