-
서블릿에서 한글 문자 인코딩하기백엔드/서블릿&JSP 2021. 1. 13. 12:32
문자 인코딩이란?
컴퓨터는 숫자 0,1로 모든 것을 인식한다.
그러나 사람은 0,1로 컴퓨터와 소통을 하기에는 제한적인 부분이 많다.
이에 사람들은 문자 코드란 것을 만들었다.
문자에 대응하는 숫자를 만들어 사람은 문자를 입력하되 컴퓨터는 숫자로 인식하도록 한 것이다.
하지만 이러한 문자 코드들은 나라마다 문자가 다른만큼 호환이 되지 않는 등의 문제가 있었다.
이에 따라 웹 상에선 이러한 문자들을 온전히 표현하기 위해 인코딩이란 것을 한다.
특히 한글의 경우 영어와는 문자 코드 자체가 다르고 복잡성때문에 이러한 인코딩을 하지 않으면
웹 상에서 제대로 표현되지 않는다.
<!DOCTYPE html> <html> <head> <title>Insert title here</title> </head> <body> <P>인코딩 테스트입니다</P> <P>어떻게 나올까요?</P> </body> </html>
위와 같은 코드가 있다고 해보자. 어떠한 인코딩없이 그냥 바로 실행하면 아래와 같은 결과물이 나온다.
인코딩이 없다면 우리는 위와 같이 깨진 글자만 볼 수 있을 것이다.
그럼 이제부터 본격적으로 문장 인코딩 처리를 해보자.
서블릿과 JSP에서 UTF-8로 문자 인코딩 처리하기
인코딩에 대해서 파고들면 이야기할건 많은데 간단히 말하면 인코딩 처리는 다음과 같이 해야 한다.
request나 response 둘 다 문자 인코딩이 필요하다.
무슨 이야기냐면 우선 그림을 보자.
그림으로 보니 더 복잡해보인다. 하지만 최대한 간단히 설명하면 다음과 같다.
1. 브라우저는 서버로 request를 할 때 전달되는 문자의 인코딩 방식을 지정한다.(흔히 UTF-8 방식 이용)
2. 하지만 그럼에도 서버는 해당 문자를 UTF-8 방식으로 받아들이지 않는다.
3. 그래서 서블릿은 전달되는 request의 문자 인코딩 방식이 어떤 것인지 서버에 알려줘야 한다.
4. 전달된 request를 처리한 뒤 response할 때 다시 한번 response의 문자 인코딩 방식(UTF-8)을 지정한다.
5. 이때 브라우저가 해당 response의 문자를 잘 읽을 수 있게 인코딩 타입 정보를 같이 전달한다.
6. 브라우저는 response와 함께 전달된 문자를 미리 지정한 인코딩 타입에 맞게 읽어들인다.
즉 문자를 전달할 때 지정, 전달 받을 때 지정, 응답 할 때 지정, 응답해서 읽을 때 지정까지
문자열은 거의 대부분 모든 request와 response 과정에서 인코딩 지정을 해줘야 함을 알 수 있다.
이번엔 실제 실습하면서 알아보자.
아래는 위와 같은 form을 HTML로 구현한 코드다.
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <form action="encoding" method="post"> 이름 <input type="text" name="name"><br> 나이 <input type="text" name="age"><br> 장소 <input type="text" name="place"><br> <input type="submit"> </form> </body> </html>
아래는 위 form을 통해 전달 받은 코드를 화면에 띄우는 서블릿이다.
form에 내용을 입력하고 제출 버튼을 누르면 해당 정보를 화면에 띄우게 만들어준다.
@WebServlet("/encoding") public class encoding extends HttpServlet{ @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out = response.getWriter(); String name = request.getParameter("name"); String age = request.getParameter("age"); String place = request.getParameter("place"); System.out.println(name); System.out.println(age); System.out.println(place); out.print("이름은 "+name+"<br>"); out.print("나이는 "+age+"<br>"); out.print("장소는 "+place+"<br>"); } }
코드만 보면 문제없이 실행될 것 같다.
하지만 위에서 말했듯 아래 이미지처럼 브라우저 상에선 문자가 깨져서 출력된다.
그럼 어디서부터 손을 대야 할까?
우선 form을 통해 전달되는 문자들의 인코딩 방식을 HTML 문서에서 미리 지정해줘야 한다.
하지만 다행히도 이미 문서를 생성할 때 해당 문서 코드는 "UTF-8"로 자동 지정되있다.
즉 위의 나왔던 결과물은 이미 HTML 과정에서 "UTF-8"로 지정했음에도 문자가 깨져서 나온다는 뜻이다.
그렇다면 추가적으로 해당 requst를 전달받는 서블릿에서 문자 인코딩 처리를 해줘야 한다.
서블릿으로 건너가서 form으로 전달한 정보가 request를 통해 어떻게 서블릿으로 전달됐는지 보자.
아래는 콘솔창을 보면 알겠지만 해당 브라우저로 문자가 전달되기 전부터 이미 문자가 깨졌다.
이 상태에선 request를 통해 받을 때부터 이미 문자가 깨져있었기 때문에 아무리 response를 할 때
인코딩 처리를 하더라도 원본이 깨져서 결국 복구가 안된다.
이럴때는 서버 측에 해당 서블릿으로 전달되는 request의 문자 인코딩 방식을 알려줘야 한다.
위와 같이 request 객체의 setsetCharacterEncoding() 메서드를 사용하면 인코딩 방식을 지정할 수 있다.
이제 request로 들어오는 문자의 인코딩을 지정하고 다시 실행해보면 아래와 같은 결과를 볼 수 있다.
아까와 달리 콘솔창에서 request를 통해 문자가 정상적으로 전달되는 것을 볼 수 있다.
하지만 여전히 브라우저 상에는 아래 이미지처럼 문자가 제대로 표시가 되지 않는다.
이미 위에서 이야기한대로 request를 처리하고 response할 때도 문자 인코딩을 해야하기 때문이다.
위와 같이 response 객체의 내장 메서드인 setsetCharacterEncoding()를 통해 인코딩 방식을 지정한다.
추가로 setContentType() 메서드를 통해 해당 데이터를 브라우저에게 데이터의 타입을 알려준다.
그래야 브라우저가 전달된 문자열을 해당 인코딩 방식에 맞게 읽어낸다.
참고로 두 메서드는 response가 이뤄지기 전에 미리 적어둬야 한다.
여튼 위와 같이 처리하고 나면 결과는 다음과 같다.
입력한 값 그대로 request를 통해 전달되고 처리 후에 response를 통해 잘 전달되고 화면 출력도 된다.
'백엔드 > 서블릿&JSP' 카테고리의 다른 글
서블릿 데이터 저장소 - request, session, ServletContext (0) 2021.01.14 서블릿 필터(filter)에 대해서 (0) 2021.01.13 서블릿 기초 형태 (0) 2021.01.13 forward와 sendRedirect 차이 (0) 2021.01.11 세션과 쿠키(Session과 Cookie) (0) 2021.01.07