Open utterances-bot opened 4 years ago
2개의 속성으 ㄹ가지고 있음
-> 2개의 속성을가지고 있음
오타 수정해주세요 :)
형은 역시 구세주...
많은 도움이 되었습니다! 감사합니다
안녕하세요! 문의 드릴게 있어서 댓글 달아요. mockMvc에서 응답에 한글이 깨져서 보다가 들어왔는데요.
해결법 3가지 중 2개가 RestTemplate인데요. 혹시 mockMvc를 사용해서 요청 시 내부적으로는 RestTemplate를 사용해서 이렇게 설정하는건가요?
추가로 "응답값을 문자열(String) 대신 객체로 변환하여 처리" 의미를 알 수 있을까요? 컨트롤러에서는 객체로 반환인데 내부에서 응답을 적절한 JSON 응답으로 만드는걸텐데요. 이걸 어떻게 객체로 변환하여 처리하란건지 이해가 안가서요 ㅠㅠ;
@ppyong 님이 물어보시는 내용이
둘 중에 어떤 경우를 말하는 것인지 궁금합니다.
첫번째 경우는, MockHttpServletResponse 에서 mockMvc 에서 사용하는 PrintingResultHandler
가 사용하는 MockHttpServletResponse
에서 캐릭터인코딩값을 가져오는 코드가 개선이 되어야 합니다.
protected void printResponse(MockHttpServletResponse response) throws Exception {
String body = (response.getCharacterEncoding() != null ?
response.getContentAsString() : MISSING_CHARACTER_ENCODING);
this.printer.printValue("Status", response.getStatus());
this.printer.printValue("Error message", response.getErrorMessage());
this.printer.printValue("Headers", getResponseHeaders(response));
this.printer.printValue("Content type", response.getContentType());
this.printer.printValue("Body", body);
this.printer.printValue("Forwarded URL", response.getForwardedUrl());
this.printer.printValue("Redirected URL", response.getRedirectedUrl());
printCookies(response.getCookies());
}
MockHttpServletResponse.getCharacterEncoding()
에서 캐릭터셋을 결정하는 코드가 여전히 Content-Type
에서 charset
값을 가져오고 있어서 기본캐릭터셋인 ISO-8859-1
를 가지고 있습니다.
private void updateContentTypeHeader() {
if (this.contentType != null) {
String value = this.contentType;
if (this.charset && !this.contentType.toLowerCase().contains(CHARSET_PREFIX)) {
value = value + ';' + CHARSET_PREFIX + this.characterEncoding;
}
doAddHeaderValue(HttpHeaders.CONTENT_TYPE, value, true);
}
}
mockMvc 의 출력물은 크게 신경쓰지 않으셔도 됩니다. 혹은 https://github.com/HomoEfficio/dev-tips/blob/master/Spring%20Test%20MockMvc의%20한글%20깨짐%20처리.md 를 참조하셔서 MockMvcBuilder 에서 필터를 추가하시면 됩니다.
이 글에서 중요한 것은,
API 측(서버)에서 스프링 부트 2.2.0 이상을 사용하면 요청헤더에
Content-Type: applicatoin/json; charset=UTF-8
으로 요청해서
charset=UTF-8
헤더가 소거되어 응답하기 때문에
클라이언트(사용자측)에서 Content-Type
에 있는 charset 을 선택하면서
String response = restTemplate.getObject("{requestUrl}", String.class);
으로 받게되는 경우 response
가 ISO_8859_1
캐릭터셋을 사용하여
한글이 깨져보일 수 있다는 것을 주의하면 됩니다.
다음과 같이 .addFilter(new CharacterEncodingFilter(StandardCharsets.UTF_8.name(), true))
를 추가할 수 있음
return MockMvcBuilders.standaloneSetup(controllers)
// .defaultResponseCharacterEncoding(StandardCharsets.UTF_8)
.setControllerAdvice(
new GlobalRestControllerExceptionHandler(),
new ApiResponseWrappingAdvisor())
.setConversionService(conversionService)
.setMessageConverters(new MappingJackson2HttpMessageConverter(JsonUtils.getMapper()))
.addFilter(new CharacterEncodingFilter(StandardCharsets.UTF_8.name(), true)); // UTF-8
그러나 이렇게 할 경우 테스트에서 Content-Type
은 변경되지 않습니다.
오랜만에 MockMvc 코드를 열어보다가 다음과 같이 선언하면 되지 않을까 하는 생각을 했습니다.
AbstractMockMvcBuilder#defaultResponseCharacterEncoding
return MockMvcBuilders.standaloneSetup(controllers)
.defaultResponseCharacterEncoding(StandardCharsets.UTF_8)
.setControllerAdvice(
new GlobalRestControllerExceptionHandler(),
new ApiResponseWrappingAdvisor())
.setConversionService(conversionService)
.setMessageConverters(new MappingJackson2HttpMessageConverter(JsonUtils.getMapper()));
요렇게 하면 아주 깔끔하게 처리됩니다. spring-test 5.3.10 에 추가됐군요.
[spring] Deprecate MediaType.APPLICATION_JSON_UTF8 in favor of APPLICATION_JSON - I'm honeymon(JiHeon Kim).
참고: Deprecate MediaType.APPLICATION_JSON_UTF8 in favor of APPLICATION_JSON · Issue #22788 · spring-projects/spring-framework
http://honeymon.io/tech/2019/10/23/spring-deprecated-media-type.html