Javaに関する様々な情報をご紹介します。

13文字化け対策

Javaに関する様々な情報をご紹介します。

文字化け対策

ここでは、Servlet・JSPでの文字化け対策について解説します。文字エンコード方法を理解してプログラム開発を行うことにより、Servlet・JSPでの日本語の文字化けを防ぐことができます。

実行環境
  • ・WindowsXP Home Edition
  • ・J2SE 1.5.0_03
  • ・Tomcat 5.0.18

ブラウザ出力時の文字コード

Servlet・JSPで作成したプログラムをブラウザに出力する際の文字コードの指定方法について解説します。HTMLでは以下の順序で文字コードの認識が行われます。

  1. HTTPヘッダのContent-Type(charset)の値
  2. HTMLファイル内のMETAタグのContent-Type(charset)の値

Tomcatなどのサーブレットコンテナは指定しない限りデフォルトの文字コード(Tomcatの場合は、ISO-8859-1)をHTTPヘッダのContent-Typeに指定します。そのため、Servlet・JSPでMETAタグを記載し、文字コードを指定していた場合でもその値は無視されます。
Servlet・JSPで文字コードを指定するためには、HTTPヘッダのContent-Typeを指定する必要があります。HTTPヘッダのContent-Typeを指定する方法を以下に記載します。

Servlet

Servletの場合は、HttpServletResponseインタフェースのsetContentTypeメソッドでHTTPヘッダのContent-Typeの指定を行います。 Content-Typeの指定は、データがブラウザに返される前に行う必要があります。

public class EncodeServ extends HttpServlet {
    public void doGet(HttpServletRequest req,
            HttpServletResponse res)
            throws ServletException, IOException {

        res.setContentType("text/html; charset=Windows-31J");

        -----------------------------
        -----------------------------

JSP

JSPの場合は、pageディレクティブのcontentType属性でHTTPヘッダのContent-Typeの指定を行います。

<%@ page language="java"
    contentType="text/html; charset=Windows-31J" %>

-----------------------------
-----------------------------

パラメータの文字コード

<form>タグなどから送信されるパラメータを受け取る際の文字コードを指定することができます。パラメータの文字コードと、ブラウザ出力時の文字コードが異なる場合はパラメータが文字化けします。

Servlet

Servletの場合は、HttpServletRequestインタフェースのsetCharacterEncodingメソッドでパラメータの文字コードを指定します。文字コードの指定は、パラメータを取得する前に行う必要があります。

public class EncodeServ extends HttpServlet {
    public void doGet(HttpServletRequest req,
            HttpServletResponse res)
            throws ServletException, IOException {

        res.setContentType("text/html; charset=Windows-31J");
        req.setCharacterEncoding("Windows-31J");

        -----------------------------
        -----------------------------

JSP

JSPの場合は、requestオブジェクトのsetCharacterEncodingメソッドでパラメータの文字コードを指定します。

<%@ page language="java"
    contentType="text/html; charset=Windows-31J" %>

<html>
<body>

<% request.setCharacterEncoding("Windows-31J"); %>

-----------------------------
-----------------------------

※ Tomcat5.xより、FORMのGETメソッドでパラメータを送信した場合、setCharacterEncodingメソッドを無視するようになりました。POSTメソッドの場合は有効です。
GETメソッドの場合、server.xmlファイルの<connector>タグのuseBodyEncodingForURI属性をtrueに指定することで、setCharacterEncodingメソッドを有効にできます。

<Connector connectionTimeout="20000" port="8080"
    protocol="HTTP/1.1" redirectPort="8443"
    useBodyEncodingForURI="true" />

JSP実行時の文字コード

Java内部ではすべての文字がUnicodeで処理されています。そのため、JSPで記載されたプログラムも、一旦UnicodeにエンコードされてJava内部で処理されています。ここでは、Unicodeにエンコードされる際のJSPの文字コードの指定方法について解説します。

JSPの文字コードの指定はpageディレクティブのpageEncoding属性で行います。JSPをEUC-JPで記載している場合は、EUC-JPと、Windows-31Jで記載している場合はWindows-31Jで記載します。pageEncoding属性が指定されていない場合は、contentType属性の値が指定されます。

<%@ page contentType="text/html; charset=Windows-31J"
    pageEncoding="Windows-31J" %>

-----------------------------
-----------------------------

pageEncoding属性の指定が正しく行われていない場合、文字化けの原因となります。あまり行うことはないと思いますが、contentType属性とpageEncoding属性を正しく指定することによりEUC-JPで記載したJSPをWindows-31Jで出力することなどができます。


JSPは一旦、Servletに変換されて実行されます。index.jspというファイル名のJSPはindex_jsp.javaというファイル名のServletに変換されて実行されます。Servletに変換されたファイルはデフォルトの設定では、$CATALINA_HOME\work\Catalina\localhost\コンテキスト名の配下にあります。

JSPからServletに変換される際、デフォルトの設定では文字コードはUnicodeで変換されます。デバッグなどのため、Servletを閲覧すると他の文字コードでJSPを記載していた場合、文字化けしています。web.xmlファイルでjavaEncodingパラメータを指定することにより、Servletへ変換する際の文字コードを指定することができます。

<servlet>
    <servlet-name>jsp</servlet-name>
    <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>

    ----------------------------

    <init-param>
        <param-name>javaEncoding</param-name>
        <param-value>Windows-31J</param-value>
    </init-param>

    ----------------------------

</servlet>

JSPでの文字コード判別手順は以下のようになります。

Javaの道_JSP_文字コード判別手順

Windows-31J

Windows-31Jとは、Windows環境で用いられている文字コードのことです。Windows環境の文字コードはShift_JISと思われている方も多いですが、正確にはWindows-31JとShift_JISは異なるものです。Windows-31JとShift_JISの違いは特殊文字をサポートしているかにあります。Windows-31Jは特殊文字として、NEC特殊文字(まる1、(株)など)、IBM特殊文字(はしご高)などをサポートしています。

JDK1.4.1からShift_JISと指定した場合の参照する文字コードが変わっています。
JDK1.4.1以前:Windows-31Jを参照
JDK1.4.1以降:Shift_JISを参照

Windows環境の場合、文字コードはWindows-31Jと指定しましょう。Windows-31Jと指定すると、実行環境に依存せずWindows-31Jが参照されます。 Shift_JISと指定した場合、Java実行環境によってはWindows-31Jが参照されたり、Shift_JISが参照されたりします。

13文字化け対策