λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
Spring

μŠ€ν”„λ§μ—μ„œ ν΄λΌμ΄μ–ΈνŠΈλ‘œ 데이터 전달 μ‹œ ν•œκΈ€μ΄ κΉ¨μ§€λŠ” 이슈 (ISO-8859-1)

by 주발2 2023. 11. 20.
λ°˜μ‘ν˜•

μ•ˆλ…•ν•˜μ„Έμš”, 졜근 ν΄λΌμ΄μ–ΈνŠΈ(Vue) 와 μ„œλ²„(Spring Boot) 연동 μ‹œ μ„œλ²„μ—μ„œ ν•œκΈ€ 데이터λ₯Ό μ „λ‹¬ν•˜λ©΄ ν΄λΌμ΄μ–ΈνŠΈμ—μ„œ ν•œκΈ€μ΄ κΉ¨μ§€λŠ” μ΄μŠˆκ°€ λ°œμƒν–ˆμ—ˆλŠ”λ°μš”, 이와 κ΄€λ ¨ν•˜μ—¬ κ°„λž΅νžˆ 정리해 λ³΄μ•˜μŠ΅λ‹ˆλ‹€.

 

 

 

원인

HttpMessageConverter μΈν„°νŽ˜μ΄μŠ€λŠ” Springμ—μ„œ HTTP request, response λ₯Ό λ³€ν™˜ν•΄ μ£ΌλŠ” μΈν„°νŽ˜μ΄μŠ€μΈλ°μš”, ν•΄λ‹Ή ν¬μŠ€νŒ…μ„ μ΄ν•΄ν•˜λŠ”λ° ν•„μš”ν•œ λ‚΄μš©μ΄λΌ κ°„λž΅ν•˜κ²Œλ§Œ μ„€λͺ…ν•˜κ³  λ„˜μ–΄κ°€κ² μŠ΅λ‹ˆλ‹€.

 

μŠ€ν”„λ§μ—μ„œ ν”νžˆ μ‚¬μš©ν•˜λŠ” @RestController μ–΄λ…Έν…Œμ΄μ…˜μ— ν¬ν•¨λ˜μ–΄ μžˆλŠ” @ResponseBody μ–΄λ…Έν…Œμ΄μ…˜μ„ μ‚¬μš©ν•  경우, HttpMessageConverter 이 λ™μž‘ν•˜κ³  λ°˜ν™˜ νƒ€μž…μ— 따라 μ μ ˆν•œ κ΅¬ν˜„μ²΄κ°€ μ‚¬μš©μ΄ λ©λ‹ˆλ‹€.

 

λŒ€ν‘œμ μœΌλ‘œλŠ” ByteArrayHttpMessageConverter, StringHttpMessageConverter, MappingJackson2HttpMessageConveter λ“±λ“±μ˜ κ΅¬ν˜„μ²΄κ°€ μ‘΄μž¬ν•©λ‹ˆλ‹€.

 

 

ν˜„μž¬ ν”„λ‘œμ νŠΈμ—μ„œ Spring Securityλ₯Ό μ‚¬μš©ν•˜κ³  있고, 인증이 μ„±κ³΅ν•œ κ²½μš°μ™€ μ‹€νŒ¨ν•œ 경우의 μΈν„°νŽ˜μ΄μŠ€μΈ AuthenticationSuccessHandler, AuthenticationFailureHandler λ₯Ό κ΅¬ν˜„ν•œ κ΅¬ν˜„μ²΄μ˜ λŒ€λž΅μ μΈ μ½”λ“œλŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

μœ„ μ½”λ“œ 쀑 ~Success, ~Failure λ©”μ„œλ“œμ—μ„œλŠ” response.getWriter().write() λ©”μ„œλ“œμ˜ νŒŒλΌλ―Έν„°μ—λŠ” String νƒ€μž…μ΄ λ“€μ–΄κ°€λŠ”λ°μš”,

 

λ”°λΌμ„œ HttpMessageConverter μΈν„°νŽ˜μ΄μŠ€μ˜ κ΅¬ν˜„μ²΄μΈ StringHttpMessageConverter ν΄λž˜μŠ€κ°€ λ™μž‘ν•˜κ²Œ λ©λ‹ˆλ‹€.

 

ν•΄λ‹Ή ν΄λž˜μŠ€μ—μ„œ κΈ°λ³Έ Charset 이 ISO-8859-1 λ‘œ μ„€μ •λ˜μ–΄ 있기 λ•Œλ¬Έμ—, λ”°λ‘œ μ„€μ •ν•΄ 주지 μ•ŠμœΌλ©΄ ν΄λΌμ΄μ–ΈνŠΈμ—μ„œλŠ” 전달받은 ν•œκΈ€μ΄ κΉ¨μ§€λŠ” λ¬Έμ œκ°€ λ°œμƒν•˜κ²Œ λ©λ‹ˆλ‹€.

 

ν…ŒμŠ€νŠΈν•΄λ³΄λ©΄ ν΄λΌμ΄μ–ΈνŠΈμ—μ„œλŠ” μ•„λž˜μ²˜λŸΌ ν•œκΈ€μ΄ κΉ¨μ Έμ„œ λ‚˜μ˜€κ²Œ λ©λ‹ˆλ‹€.

 

λ„€νŠΈμ›Œν¬ νƒ­μ—μ„œλ„ 확인해보면 응닡 ν—€λ”μ˜ Content-Type 의 charset 이 ISO-8859-1 μž…λ‹ˆλ‹€.

 

 

 

 

ν•΄κ²°μ±…

더 λ§Žμ€ 방법이 μ‘΄μž¬ν•  수 μžˆκ² μ§€λ§Œ, μ œκ°€ 찾은 방법은 크게 3가지 정도 μ‘΄μž¬ν•  것 κ°™μ•„μš”.

 

1. properties(yml) νŒŒμΌμ— server 의 인코딩을 κ°•μ œλ‘œ UTF-8 둜 μ„€μ •ν•˜κΈ°

server:
  servlet:
    encoding:
      force-response: true
      charset: UTF-8

 

 

2. AuthenticationSuccessHandler, AuthenticationFailureHandler μΈν„°νŽ˜μ΄μŠ€μ˜ κ΅¬ν˜„μ²΄μ—μ„œ 인코딩 μ„€μ •ν•˜κΈ°

    @Override
    public void onAuthenticationFailure(HttpServletRequest request,
                                        HttpServletResponse response,
                                        AuthenticationException exception) throws IOException {

        ...

	// 인코딩 μ„€μ •
        response.setCharacterEncoding(StandardCharsets.UTF_8.name());
        
        ...
    }

 

 

3. WebMvcConfigurer μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œ 클래슀

@Configuration
@EnableWebMvc
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        StringHttpMessageConverter converter = new StringHttpMessageConverter(StandardCharsets.UTF_8);
        converter.setDefaultCharset(StandardCharsets.UTF_8);

        converters.add(converter);
        
        // HTTP Response μ—μ„œ JSON λ³€ν™˜λ„ ν•„μš”ν•  경우 μΆ”κ°€
        converters.add(new MappingJackson2HttpMessageConverter());
    }
}

 

μœ„ 방법 쀑 ν•˜λ‚˜λ‘œ μ„€μ •ν•˜λ©΄ 해결이 λ˜λŠ”λ°μš”, μ €λŠ” 2번 λ°©μ‹μœΌλ‘œ μ μš©μ„ ν–ˆμŠ΅λ‹ˆλ‹€.

1번의 경우, μ „μ—­μœΌλ‘œ μ„€μ •ν•˜κΈ°μ— ν˜Ήμ‹œ λͺ¨λ₯Ό λ¬Έμ œκ°€ μ‘΄μž¬ν•  수 μžˆμ„ 것 κ°™μ•˜κ³ ,

3번의 경우 Config 클래슀λ₯Ό ꡳ이 λ§Œλ“€ ν•„μš”λ„ μ—†λ‹€κ³  μƒκ°ν–ˆμŠ΅λ‹ˆλ‹€.

 

 

 

ν…ŒμŠ€νŠΈ 해보면 μ•„λž˜μ™€ 같이 ν•œκΈ€μ΄ μ•ˆκΉ¨μ§€κ³ , Content-Type 의 charset도 μ •μƒμ μœΌλ‘œ UTF-8둜 λ‚˜μ˜€λŠ” 것을 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

λ°˜μ‘ν˜•

λŒ“κΈ€