MediaType.APPLICATION_JSON_UTF8
Deprecated
Content-Type
으로 전달되는 속성값은 1가지 성질만 가진다.MediaType.APPLICATION_JSON_UTF8
의 경우 application/json; charset=UTF-8
로 속성 2개를 가지고 있음Content-Type: application/json;charset=UTF-8
요청에 대해 Content-Type: application/json
으로 응답StringHttpMessageConverter
기본 Charset 은 ISO_8859_1
이다.
Deprecated MediaType.APPLICATION_JSON_UTF_8
/**
HelloController
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@RestController
public class HelloController {
@GetMapping("/greeting")
public Greeting greeting(@RequestParam(defaultValue = "허니몬") String name) {
return new Greeting("Hello, " + name);
}
@Getter
public static class Greeting {
private String statement;
public Greeting(String statement) {
this.statement = statement;
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@RunWith(SpringRunner.class)
@WebMvcTest(HelloController.class)
public class HelloControllerTest {
@Autowired
private MockMvc mvc;
@Test
public void test() throws Exception {
ResultActions result = mvc.perform(get("/greeting")
.contentType(MediaType.APPLICATION_JSON_UTF8));
//then
result
.andExpect(status().isOk())
.andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(jsonPath("$.statement").value("Hello, 허니몬"));
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
MockHttpServletRequest:
HTTP Method = GET
Request URI = /greeting
Parameters = {}
Headers = [Content-Type:"application/json;charset=UTF-8"]
Body = null
Session Attrs = {}
Handler:
Type = io.honeymon.training.programming.api.HelloController
Method = public io.honeymon.training.programming.api.HelloController$Greeting io.honeymon.training.programming.api.HelloController.greeting(java.lang.String)
Async:
Async started = false
Async result = null
Resolved Exception:
Type = null
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 200
Error message = null
Headers = [Content-Type:"application/json;charset=UTF-8"] // charset 유지
Content type = application/json;charset=UTF-8
Body = {"statement":"Hello, 허니몬"}
Forwarded URL = null
Redirected URL = null
Cookies = []
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
MockHttpServletRequest:
HTTP Method = GET
Request URI = /greeting
Parameters = {}
Headers = [Content-Type:"application/json;charset=UTF-8"]
Body = null
Session Attrs = {}
Handler:
Type = io.honeymon.training.programming.api.HelloController
Method = io.honeymon.training.programming.api.HelloController#greeting(String)
Async:
Async started = false
Async result = null
Resolved Exception:
Type = null
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
Attributes = null
MockHttpServletResponse:
Status = 200
Error message = null
Headers = [Content-Type:"application/json"] // charset 제거
Content type = application/json
Body = {"statement":"Hello, íë몬"}
Forwarded URL = null
Redirected URL = null
Cookies = []
Content-Type
에서 Charset
빠짐
Content-Type: application/json; charset=UTF-8
을 Content-Type: application/json;
으로 변경함RestTemplate
를 그대로 사용하는 경우 문자열(String
) 으로 응답값을 받아 처리하는 경우 한글 깨짐
StringHttpMessageConverter
의 기본 Charset 이 StandardCharsets.ISO_8859_1
으로 되어 있다.Content-Type
에서 charset
을 무시(제거)StringHttpMessageConverter.getContentTypeCharset
메서드에서 기본Charset StandardCharsets.ISO_8859_1
처리
1
2
3
4
5
6
7
8
9
10
private Charset getContentTypeCharset(@Nullable MediaType contentType) { // contentType == MediaType.APPLICATION_JSON
if (contentType != null && contentType.getCharset() != null) {
return contentType.getCharset();
}
else {
Charset charset = getDefaultCharset(); //DEFAULT_CHARSET = StandardCharsets.ISO_8859_1
Assert.state(charset != null, "No default charset");
return charset;
}
}
String
) 대신 객체로 변환하여 처리 ← 추천!!
MappingJackson2HttpMessageConverter
기본 Charset 은 UTF-8
RestTemplateBuilder.addtionalMessageConverts
메시지 컨버터 추가
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
RestTemplate restTemplate = new RestTemplateBuilder()
.rootUri(ROOT_URI)
.additionalInterceptors(new ApiClientHttpRequestInterceptor(DEFAULT_AUTHORIZATION))
.additionalMessageConverters(
new StringHttpMessageConverter(StandardCharsets.UTF_8),
new MappingJackson2HttpMessageConverter())
.setConnectTimeout(Duration.ofSeconds(10))
.setReadTimeout(Duration.ofSeconds(5))
.build();
public static class ApiClientHttpRequestInterceptor implements ClientHttpRequestInterceptor {
private final String apiKey;
public ApiClientHttpRequestInterceptor(String apiKey) {
Assert.hasText(apiKey, "Required apiKey.");
this.apiKey = apiKey;
}
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
HttpHeaders headers = request.getHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
if (StringUtils.hasText(apiKey)) {
headers.set(HttpHeaders.AUTHORIZATION, apiKey);
}
return execution.execute(request, body);
}
}
기본 Charset 이UTF-8
인 StringHttpMessageConverter
를 RestTemplate 추가
1
2
3
restTemplate.getMessageConverters()
.add(0, new StringHttpMessageConverter(StandardCharsets.UTF-8));
// 기본설정된 StringHttpMessageConverter 보다 앞에 추가하여 미리 처리하도록 하는 케이스
Spring Boot Http Encoding Default: UTF-8
Charset
매개변수가 정의되어 있지 않다.