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>