그럼에도 불구하고

👨‍💻

[Servlet] 한글깨짐 해결 / Servlet Filter 본문

Java, Servlet/Servlet, Jsp

[Servlet] 한글깨짐 해결 / Servlet Filter

zenghyun 2022. 11. 3. 03:07

 

게시글을 입력받을 수 있는 html 파일이 있다.

 

 

post.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<div>
	<form action="notice-reg" method="post">
	<div> 
		<label>제목</label><input name="title" type="text">
	</div>
	<div>
		<label>내용: </label>
		<textarea name="content"></textarea>
		<input type=submit value="등록">
	</div>
	</form>
	</div>
</body>
</html>

 

 

 

 

 

post.java 

package com.zenghyun.web;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/notice-reg")
public class post extends HttpServlet {
	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setCharacterEncoding("UTF-8");
		response.setContentType("text/html; charset=UTF-8");
		PrintWriter out = response.getWriter();
		String title = request.getParameter("title");
		String content = request.getParameter("content");
		
		out.println(title + "<br>");
		out.println(content + "<br>");
	}
		
	}

 

 

 

 

post.html 화면

 

 

post.html 화면에서 제목과 내용에 한글을 입력하고 등록을 누르면

 

 

 

 

결과 값이 깨져서 나오게 된다.

 

 

 

 

[ 한글이 깨지는 이유 ]

UTF-8로 보낼 때, 기본적으로 멀티바이트 문자로 보내게 된다.

문자 하나당 숫자 1개가 필요한데 영어의 경우 1byte로 충분하지만,

한글의 경우 2byte가 필요하다. 

 

그런데 웹서버의 경우 1byte씩 인식해서 한글이 깨지게 된다. 

(웹서버는 기본적으로 USO-8859-1로 인식하기 때문) 

 

그래서 해결방법으로 request.setCharacterEncoding("UTF-8"); 를 쓰면 된다.

 

response.setCharacterEncoding("UTF-8");와 다른 점이 있다면, 

 

request.setCharacterEncoding("UTF-8")는 클라이언트가 웹서버로 request 할 때에 초점을 맞춘다면

 

response.setCharacterEncoding("UTF-8")  는 웹서버가 클라이언트에게 response 할 때에 초점이 맞춰져 있다. 

 

그래서 클라이언트가 한글 값을 보낸다면 request.setCharacterEncoding("UTF-8"); 를 해줘야 한다. 

 

 

 

 


 

request.setCharacterEncoding("UTF-8"); 추가

package com.zenghyun.web;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/notice-reg")
public class post extends HttpServlet {
	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setCharacterEncoding("UTF-8");
		response.setContentType("text/html; charset=UTF-8");
        request.setCharacterEncoding("UTF-8");
		PrintWriter out = response.getWriter();
		String title = request.getParameter("title");
		String content = request.getParameter("content");
		
		out.println(title + "<br>");
		out.println(content + "<br>");
	}
		
	}

 

 

 

 

결과

 

 

 

 


 

한글깨짐은 해결됐지만 

 

아쉬운 점이 있다.

 

매번 코드 작성을 할 때마다

 

request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=UTF-8");

 

작성을 할 필요가 있을까?

 

이 번거로움을 해결하기 위해 servlet filter를 이용하면 된다.

 

 

 

 

[ Servlet Filter ]

WAS와 Servlet 사이에서 request와 reponse를 받을 때 사이에 만들 수 있는 filter를 말하며, 

이 filter가 있으면 request와 response를 할 때 항상 거치게 된다. 

 

 

 

 

 

내가 작업하고 있는 패키지 안에 filter 패키지를 만들고 안에서 만든 java file이다. 

 

Filter를 implements하고 doFilter를 Override 하고 작성한 것인데

 

여기서 중요한것은 chain이다.

 

chain.doFilter(request, response)

 

request할 때와 response 할 때 이 filter를 거치게 한다는 뜻이다.

 

치기 전은 before filter

 

거친 후는 after filter로 나눠서

 

내가 원하는 작업을 지시할 수 있다. 

 

filter를 거치기 전에

 

request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=UTF-8"); 를 작성하고 

 

 

마지막으로 @WebFilter("/*")를 써주면 된다.

 

 

 

※ @WebFilter("/*") : 모든 경로에 있는 파일에 이 filter를 적용시킨다.

Comments