文字セットとエンコードの理解

文字セットは、バイトを文字にマッピングするテーブルです。Java では内部的に、すべてのコンテンツをエスケープされたASCII Unicode 文字セットで処理します。Java クラスをコンパイルするとき、Java コンパイラは、クラスのコンテンツをシステムの文字セットからエスケープされたASCII Unicode 文字セットに変換します。

各文字セットには、バイトシーケンスを定義する独自のエンコード/デコードのアルゴリズムがあります。エンコードは、リクエストの作成時にクライアントサイドの Web ブラウザで、また、レスポンスの作成時にサーバサイドの Java で実行されます。開発者は、エンコードメカニズムやデコードメカニズムを提供する必要はなく、クライアントの Web ブラウザによって使用される文字セットを設定、取得できます。

ブラウザは、HTTP Content-Type ヘッダーで指定された文字セットを使用して、画面上でバイトを文字に変える方法を決定します。

一般的な文字セットは次のとおりです。

Java では、文字セットに大文字と小文字の区別がないので、値 Shift_JIS と値 shift_jis は等価です。

1 つのページで複数の文字セットを使用するには、UTF-8 文字セットのエンコードを使用します。

一般的な文字セットのリストについては、http://www.eleves.ens.fr:8080/home/madore/computers/unicode/cstab.html をご覧ください。

Internet Explorer バージョン 5 以降でサポートされている文字セットのリストについては、http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/reference/charsets/charset4.asp をご覧ください。

Java でサポートされているエンコード文字セットの詳細については、http://java.sun.com/j2se/1.3/docs/guide/intl/encoding.doc.html をご覧ください。

サーブレットでの文字セットの設定

Content-Type HTTP ヘッダーによって、レスポンスオブジェクトによってエンコードされる文字セットが定義されます。Content-Type ヘッダー内の定義の形式は、
charset=character_set です。このヘッダーでは MIME タイプも定義されますが、
それに関してはこのセクションでは説明しません。

クライアントのブラウザはヘッダーの charset を読み取って、クライアントの画面でページを正しくレンダリングできるように、レスポンスのエンコードを判断します。クライアントは、charset のついたレスポンスを受け取ったとき、文字セットをデコードできる必要があります。正しく出力するには、ブラウザがその文字セットをサポートしていること、および、システムが適切なフォントにアクセスできる必要があります。

サーブレット API には、Content-Type HTTP ヘッダーを設定する、次のような便利なメソッドが用意されています。

このセクションでは、これらの方法について説明します。

次の setHeader を使用して、HTTP ヘッダーを明示的に変更することもできます。

レスポンスオブジェクトで適切なエンコードを使用するには、コンテンツタイプを定義した後で、getWriter を呼び出す必要があります。PrintWriter では、デフォルトで ISO-8859-1 文字セットが使用されます。

1 つのページで複数の文字セットを使用するには、UTF-8 文字セットのエンコードを使用します。

setContentType の使用

HTTP Content-Type ヘッダーによって文字セットが設定されたのと同様に、
setContentType メソッドによってレスポンスの MIME タイプが設定されます。charset によって、クライアントのブラウザでのページの表示に使用するデコードアルゴリズムの種類が、クライアントのブラウザに示されます。

次の例では、Content-Type ヘッダーを日本語文字セットに設定します。

response.setContentType("text/html; charset=Shift_JIS");
PrintWriter out = response.getWriter();

setLocale の使用

setLocale メソッドによって、レスポンスの文字セット、HTTP Content-Language ヘッダー、および HTTP Content-Type ヘッダーが設定されます。Content-Language ヘッダーは、しばしばブラウザに無視されます。setLocale を使用すると、setContentType を使用する場合よりも、より詳細に言語設定を管理できます。その場合は、Locale オブジェクトを用意する必要があります。

次の例では、レスポンスオブジェクトの文字セットを Shift_JIS に定義します。

response.setContentType("text/html");
response.setLocale(new Locale("ja",”")); //ja のデフォルト文字セットを 
Shift_JIS に設定します
PrintWriter out = response.getWriter();

JSP での文字セットの設定

次の例に示すように、page ディレクティブの contentType 属性を使用して、JSP で文字セットを定義します。

<%@ page contentType="text/html; charset=Shift_JIS" 
pageEncoding="Shift_JIS" %>

1 つのページで複数の文字セットを使用するには、次の例に示すように、UTF-8 文字セットのエンコードを使用します。

<%@ page contentType="text/html; charset=utf-8" %>

非デフォルト文字セットでのコンパイル

デフォルトではない文字セットで JSP やサーブレットを作成する場合は、コンパイラでクラスファイルが正しいエンコードに変換されるように特に注意する必要があります。このセクションでは、サーブレットと JSP をコンパイルするときのエンコードタイプの変更方法を説明します。

サーブレットのコンパイル

Java クラスをコンパイルするときは、-encoding オプションとそれに続けてエンコードタイプを追加することにより、クラスのエンコードを設定します。-encoding オプションを指定しない場合、Java コンパイラはシステムの現在のエンコードをデフォルトとして使用します。次の行は、日本語エンコードでサーブレットをコンパイルする encoding オプションを示しています。

%> javac -encoding Shift_JIS -classpath c:/jrun4/lib/jrun.jar 
MyJapaneseServlet.java

デフォルトのエンコードタイプは、file.encoding システムプロパティで定義されます。次のコードで示すように、getProperties メソッドを使用して、システムプロパティをチェックできます。

...
Properties properties = System.getProperties();
Enumeration keys = properties.propertyNames();
while(keys.hasMoreElements()) {
  String key = (String) keys.nextElement();
  System.out.println(key + " = " + properties.getProperty(key));
}
...

JSP のコンパイル

JSP では、page ディレクティブの pageEncoding 属性を使用して、コンパイル時に使用するエンコードタイプが決定されます。

次の例は、ページを日本語文字セットでエンコードします。

<% page contentType="text/html; charset=UTF-8" pageEncoding="EUC-JP" 
%>

ページのエンコードは、ページがエディタで保存されたときのエンコードタイプに一致する必要があります。