Java Servlet 文字化け対策

DBマガジン-2010/02より
request,responseに対し、setCharacterEncofing()でISO-2022-JPを指定する。getWriterを実行する前に設定すること。

データをpostしてpdfを生成するServletがあった場合

public class GeneratePdf extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
	throws ServletException, IOException{
		try {
			request.setCharacterEncoding("ISO-2022-JP");
			response.setCharacterEncoding("ISO-2022-JP");
			response.setContentType("text/html;charset=ISO-2022-JP");
			PrintWriter out = response.getWriter();
			out.println("<html><body><form action=\"generatepdf\" method=\"post\"><input type=\"submit\"/><textarea name=\"dat\"></textarea></form></body></html>");
		} catch (Exception e) {
			throw new IllegalStateException(e);
		}
		
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
	throws ServletException, IOException{
		try {
			request.setCharacterEncoding("ISO-2022-JP");
			response.setCharacterEncoding("ISO-2022-JP");
			response.setContentType("text/html;charset=ISO-2022-JP");

			//PDF生成用データテキストの作成
			FileOutputStream fileOutputStream;
			OutputStreamWriter outputStreamWriter;
			BufferedWriter bufferedWriter;
			fileOutputStream = new FileOutputStream("data.txt");
			outputStreamWriter = new OutputStreamWriter(fileOutputStream,"Shift_JIS");
			bufferedWriter = new BufferedWriter(outputStreamWriter);
			bufferedWriter.write(request.getParameter("dat"));
			bufferedWriter.close();

			Process p;
			p = Runtime.getRuntime().exec("generatepdf.exe data.txt");
			p.waitFor();

			out.println("<html>");
			//省略
		} catch (Exception e) {
			throw new IllegalStateException(e);
		}

}

データの書き出しにFileWriterを使用すると文字コードが使用できないので、文字化けしちゃう場合はFileOutputStreamで文字コードを指定する。(何故かローカルのwindows環境では化けないのにサーバのwindows環境では化けてしまう・・ってことがあったので)

例では、postするformを自身で出力してるので、ISO-2022-JPで統一してるが、postするformを利用者側で生成されてる場合は注意が必要。例えばC/Sシステムでhtmlを動的に生成してる場合などはwindows環境ならShift_JISになるので、

request.setCharacterEncoding("Shift_JIS");

とする必要がある


文字コードが基本1つで、Servletいっぱいあって、毎回エンコするのが面倒な場合はフィルタを使う

package util;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class CharacterEncodingFilter implements Filter {

	private String encoding = null;
	
	public void destroy(){
		encoding = null;
	}
	
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,ServletException{
		if(encoding != null){
			request.setCharacterEncoding(encoding);
		}
		chain.doFilter(request,response);
	}

	public void init(FilterConfig filterConfig) throws ServletException{
		this.encoding = filterConfig.getInitParameter("encoding");
	}

}

web.xml

<filter>
	<filter-name>CharacterEncodingFilter</filter-name>
	<filter-class>util.CharacterEncodingFilter</filter-class>
	<init-param>
		<param-name>encoding</param-name>
		<param-value>ISO-2022-JP</param-value>
	</init-param>
</filter>
	
<filter-mapping>
	<filter-name>CharacterEncodingFilter</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>