문자가 깨지는 이유는
브라우저 => 서버
서버 => 브라우저
환경이 변할 때, 환경별로 설정된 인코딩 방식이 다르기 때문이다. 그러므로 인코딩 설정을 바꾸어야 한다.
브라우저 => 서버 (Request)
요청에는 크게 두 가지가 있다.
Get 방식, Post 방식
이전 포스팅에서 자세히 다루어 본대로, 웹서버에서 Get 방식으로 url로 넘길 때와 Post 방식으로 HTTP body 안에 데이터를 넣고 전송하는 방식은 서로 인코딩 방식이 다르다. 그래서 Get 방식과 Post 방식은 인코딩을 설정하는 방식도 다르다.
Post 방식의 경우, 이클립스로 서블릿을 개발하면서 JAVA 메소드로 인코딩을 할 수 있다. request.setCharacterEncoding("UTF=8"); 로 간단히 인코딩 방식을 설정할 수 있다. HTTP Body가 아닌 url로 데이터를 전달하는 Get 방식은 JAVA 메소드로 인코딩 설정이 불가능하다.
Get방식의 인코딩 방식을 설정하려면 server.xml 파일을 수정해야 한다.
server.xml을 켜서 인코딩 속성을 추가하면 된다. 인코딩을 설정할 수 있는 속성은 두 가지이다.
URIEncoding 속성은 url로 넘어오는 데이터 인코딩 방식을 설정하는 속성으로 디폴트는 UTF-8이다. 그러므로 URIEncoding 설정을 하지 않으면 Get 방식으로 들어오는 데이터는 UTF-8 방식으로 인코딩되는 것이다.
useBodyEncodingForURI 속성은 Post 방식 설정시 사용했던, request.setCharachterEncoding() 메소드의 방식대로 그대로 인코딩을 설정하는 것이다. 디폴트가 false이므로 설정하려면 true로 바꾸어줘야한다.
우선 웹브라우저의 문자셋을 EUC-KR로 바꾸어준다.
서블릿에 Get 방식으로 데이터를 전달한다. 그리고 콘솔창에 데이터가 어떻게 전달되었는지 확인해본다.
문자가 깨진 채로 전달되었다. server.xml에 인코딩 설정을 바꾸지 않았기에 디폴트 값대로 문자를 인식하기 때문이다. 그럼 server.xml에서 속성을 수정해보자.
Connector 태그를 찾아 빨간 상자와 같이, useBodyEncodingForURI속성을 추가해주면 된다. 그러면 서블릿 request 객체에 설정된 인코딩 방식대로 인코딩이 이루어질 것이다. Post 방식의 인코딩을 설정하면 useBodyEncodingForURI 속성에 의해 Get방식의 Encoding 방식도 EUC-KR로 바뀔 것이다.
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
request.setCharacterEncoding("EUC-KR"); // Post 방식 인코딩 설정
String get_kor = request.getParameter("get_kor"); // 데이터 가져오기
System.out.println("GET 방식 : " + get_kor); // 서버 콘솔에 출력
}
Post 방식의 인코딩을 설정하면 useBodyEncodingForURI 속성에 의해 Get방식의 Encoding 방식도 EUC-KR로 바뀔 것이다.
다시 실행해보면 정상 출력이 되었음을 알 수 있다. Get 방식과 Post 방식 모두 서버에 깨지지 않은 채, 온전히 전달되었음을 확인 할 수 있다.
서버 => 브라우저 (Response)
서버까지는 안전하게 데이터가 전달되었다. 이제 서버에서 데이터를 처리한 후, 다시 브라우저로 결과를 보내야 한다. 이때에도 당연히 인코딩 설정이 있어야 한다.
서버에서 브라우저로 데이터를 보낼 때는 Response 객체를 사용한다. 인코딩시 필요한 Response 객체의 메소드는 두 가지를 기억하면 된다.
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException{
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=UTF-8");
}
response.setCharacterEncoding()은 데이터를 브라우저로 보낼 때, 서버 측에서 문자를 인코딩하는 방식을 설정할 때 사용된다. UTF-8로 설정하면 서버는 UTF-8 방식으로 데이터를 인코딩한 후, 브라우저로 전송한다.
response.setContentType()의 경우, Content Type을 설정할 때 사용한다. Content Type은 주로 MIME Type을 나타낸다. MIME Type이란, 웹브라우저가 데이터의 종류(이미지, 음악, 텍스트 등등)에 따라 알맞게 처리할 수 있도록 방식을 설정해주는 것이다.
response.setContentType("text/html;charset=UTF-8") 로 서블릿 코드를 작성한 후 데이터를 전송한 후, F12를 눌러 확인하면 위와 같이 설정되어졌음을 알 수 있다. MIME-TYPE은 HTTP 객체의 헤더부분에 담겨져, 웹브라우저에게 전달된다.
그리고 웹브라우저는 MIME-TYPE에 맞게 데이터를 처리하고 화면에 출력한다. 이렇게 Content-Type을 지정해주지 않으면, 웹브라우저 종류 별로(익스플로러, 크롬, 웨일..) 디폴트된 설정으로 데이터를 처리하기 때문에 환경에 따라 화면에 출력되는 결과가 달라질 수 있다.
Content-Type을 지정해주지 않으면, 이와 같이 출력결과가 달라진다. 익스플로러는 개인이 브라우저 인코딩 방식을 설정할 수 있어서 UTF-8로 설정했다. 그러나 크롬은 인코딩 설정을 변경하는 것이 불가능하다. 이렇게 환경마다 설정이 서로 다르니, Content-Type을 지정해주어 브라우저에게 어떤 방식으로 데이터를 처리해야하는지 알려줘야 한다.
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException{
response.setCharacterEncoding("UTF-8"); //response 인코딩 설정
response.setContentType("text/html; charset=UTF-8"); // MIME 설정
PrintWriter out = response.getWriter(); // 출력 스트림 생성
request.setCharacterEncoding("EUC-KR"); // request Post 방식 인코딩 설정
String post_kor = request.getParameter("post_kor"); // request
out.println("POST 방식 : " + post_kor);
}
서블릿을 이렇게 작성 한 후, HTML를 통해 접근해보자.
이렇게 한글이 깨지지 않고 정상적으로 잘 출력됨을 알 수 있다.
정리
1. 브라우저에서 서버로 Request 시, Get과 Post에 따라 인코딩 방식이 달라진다.
2. 서버에서 브라우저로 Response 시, 서버쪽 인코딩 뿐만 아니라 브라우저 Content-Type도 설정해주어야 한다.
'Web언어 > JSP' 카테고리의 다른 글
[JSP] 동적(Dynamic) 페이지란? (0) | 2022.01.29 |
---|---|
[ JSP ] 상태 유지 ( Session, Cookie ) (0) | 2022.01.25 |
[ JSP ] 인코딩(Encoding)을 하는 이유 (3) | 2021.06.21 |
[ JSP ] HttpServlet이란? (0) | 2021.06.21 |
[ JSP ] Servlet 과 ServletConfig (0) | 2021.06.20 |