본문 바로가기
Programing/Spring

Ajax 호출 시 @ResponseBody로 한글을 내려줄 때 ???? 로 깨지는 현상

by Tomining 2017. 11. 24.
들어가며...

Ajax로 호출할 때, 응답값을 한글로 내려 준 경우 ???? 로 노출되는 현상을 겪었다.
Javascript에서 처리한 한글은 잘 되고, 다른 api 결과로 받은 한글 값을 그대로 전달하면 정상적으로 한글이 잘 노출되었다.
@RequestMapping(value = “/save”, method = RequestMethod.POST)
@ResponseBody
public String save() {
    //…
    String result = api.call(parameter);
    if (“SUCCESS”.equals(result)) {
        return “성공”;    //한글 깨짐
    } else {
        return result;    //한글 정상 노출
    }
}
정확히 위 코드는 아니지만, 결국은 Java에서 한글을 그대로 return 하고 있는 코드였다.
왜 한글이 깨질까?

삽질 시작

1.Tomcat 한글 설정

보통 서버와 통신시 파라메터 관련 한글 깨짐 현상이 있으면 제일 첫 번째로 의심하는 부분이다.

<Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" URIEncoding="UTF-8”/>

<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" URIEncoding="UTF-8"/>
효과 없음...

2.페이지 인코딩

<%@ page language=“java” contentType=“text/html” pageEncoding=“UTF-8” %>
효과 없음...

3.meta 설정

<meta http-equiv=“Content-Type” content=“text/html; charset=UTF-8”>
효과 없음...

4.StringHttpMessageConverter 설정

<bean class=“org.springframework.http.converter.StringHttpMessageConverter”>
    <property name =“supportedMediaTypes”>
        <list>
            <value>text/html;charset=UTF-8</value>
        </list>
    </property>
</bean>
효과 없음...

5.@RequestMapping.produces 설정

@RequestMapping(value=“/save”, produces=“application/text;charset=utf8”)
@ResponseBody
public String save() {
     //…
     return “한글…"
}
해결...
produces 속성은 처음으로 접한 속성이다. 어떤 기능을 하는 것일까?
https://blog.outsider.ne.kr/902 여기서 아래와 같이 소개하고 있다.

16.3.2.5 생산가능한 미디어 타입(Producible Media Types)
생산가능한 미디어 타입의 목록을 지정해서 주요 매핑을 제한할 수 있다. Accept 요청헤더가 이러한 값 중 하나와 일치할 때만 요청이 매칭될 것이다. 게다가 produces 상태를 사용하면 produces 조건에 지정한 미디어 타입과 관련된 응답을 생성하는데 사용한 실제 컨텐트 타입을 보장한다. 예를 들면 다음과 같다.

Java

@Controller
@RequestMapping(value = "/pets/{petId}", method = RequestMethod.GET, produces="application/json")
@ResponseBody
public Pet getPet(@PathVariable String petId, Model model) {
  // 구현부는 생략한다
}
consumes에서처럼 생산가능한 미디어타입 표현식에는 text/plain의 Accept 헤더값을 가진 요청을 제외한 모든 요청에 매칭되도록 !text/plain처럼 부정문을 사용할 수 있다.

Tip

produces 조건은 타입수준과 메서드 수준에서 지원한다. 다른 대부분의 조건과는 달리 타입수준에서 사용했을 때 메서드수준의 producible 타입은 타입수준의 producible 타입을 확장하는 게 아니라 오버라이드한다.

4번 방법과 유사한 방식인데. 4번이 왜 안 된 것인지는 잘 모르겠다.
MessageConverter 기능을 좀 더 공부해 봐야겠다.


참고