日本語の表示とコンテンツタイプについて
5.1 日本語の表示とコンテンツタイプについて
これまでのサーブレットでは、リクエストの結果として文字を画面に表示していましたが、これは下の図のような流れで行われています。
図 5.1.1: 文字列が画面に表示されるまでの流れ
文字列は、そのままの状態でブラウザに送られているわけではなく、特定のデータに変換されてブラウザ側に送信されています。
5.1.1 日本語を表示してみよう
前章までに作成したサーブレットでは、英文字のみを画面に表示しました。これから、日本語を表示するサーブレットを作成していきます。
日本語を表示するプログラム
Webブラウザで英文字と日本語を表示するプログラムを作成し、表示された結果を確認します。
なお、web.xmlのソースコードはweb.xmlファイルに追加するソースのみを記述しています。
3.1.4項の「web.xmlの内容」を参考に、適切な位置に追加してください。
実行結果
アプリケーション構成
➢ JapaneseServlet1.java① ソース・フォルダ :web_basic/WEB-INF/src
② パッケージ :ch05
③ 名前 :JapaneseServlet1
④ スーパークラス :javax.servlet.http.HttpServlet
⑤ アクセスURL :http://localhost:8080/web_basic/JapaneseServlet1
package ch05; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class JapaneseServlet1 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out = response.getWriter(); out.println("日本語を表示するServlet!"); } }➢ web.xml(10行目から13行目にサーブレット、22行目から25行目にサーブレットマッピングを追加)
<servlet> <servlet-name>JapaneseServlet1Mapping</servlet-name> <servlet-class>ch05.JapaneseServlet1</servlet-class> </servlet> <servlet-mapping> <servlet-name>JapaneseServlet1Mapping</servlet-name> <url-pattern>/JapaneseServlet1</url-pattern> </servlet-mapping>
解説
このサーブレットでは、「日本語を表示するservlet!」というメッセージを画面に出力する予定でしたが、日本語の部分が「???????」と表示されてしまっています。このように、表示させようとした文字が別の文字として表示されてしまうことを「文字化け」と呼びます。今までのプログラムでは英文字しか表示しなかったので特に設定をしませんでしたが、ブラウザに日本語を正常に表示させるためには、「コンテンツタイプ」の設定を行い文字コードの指定をする必要があります。
サーブレットでは、文字コードが設定されていない場合、デフォルト文字コードの「ISO-8859-1(Latin1)」が設定されているものとして画面の出力が行われます。「ISO-8859-1(Latin1)」は西欧系の言語ですので、日本語に対応していません。その結果、日本語の部分が「???????」と表示されてしまいます。
図 5.1.2: 文字化けの流れ
5.1.2 コンテンツタイプとは
コンテンツタイプとは、Webブラウザ側に返すファイルやデータの種類を指定する設定です。
Webブラウザからのリクエストの結果として返すファイルの種類をコンテンツタイプに設定することで、ファイルの種類をWebブラウザ側が知ることができます。そして、その種類に応じて、画面にそのまま表示したり、ファイルとして保存したり、他のアプリケーションを起動して表示したりと、動きを変えることができるのです。
コンテンツタイプは、以下の書式でサーブレット内の処理の初めに定義します。
このコンテンツタイプを設定するsetContentType()メソッドの引数には「MIMEタイプ」と「文字エンコーディング」を指定することができます。
コンテンツタイプの別の書き方本テキストではsetContentType()メソッドにMIMEタイプと文字エンコーディングを一緒に指定していますが、別々に記述することも可能です。その場合は、setContentType()メソッドの他に、setCharacterEncoding()メソッドもあわせて記述します。
MIMEタイプ
MIMEタイプとは、インターネット上でのデータの種類のことを表すもので、主なMIMEタイプには以下通りです。
表 5.1.1
文字エンコーディング
文字エンコーディングとは、ブラウザに表示する文字のエンコードの種類のことです。
サーブレットからブラウザに文字列を送る場合、Webサーバでエンコード(符号化)と呼ばれる処理が行われ、データがブラウザに送られます。また、ブラウザではデコード(復号化)と呼ばれる処理を行い画面に表示します。
・ エンコード:文字列を指定された文字コードのデータに変換する。
・ デコード:文字コードのデータを元の文字列に変換する。
このエンコードとデコードの処理は次の図のような流れで行われます。
図 5.1.3: エンコードとデコードの流れ
日本語を扱う場合、指定された文字セットが日本語に対応していないと、デコードの処理で問題が発生し、文字化けの原因となります。
主な文字エンコーディングには以下のようなものがありますので覚えておきましょう。
表 5.1.2
日本語を正常に表示するプログラム
このプログラムでは、前項で作成した文字化けを起こすプログラムに、コンテンツタイプを設定します。日本語が正しく表示されることを確認しましょう。
実行結果
アプリケーション構成
➢ JapaneseServlet2.java① ソース・フォルダ :web_basic/WEB-INF/src
② パッケージ :ch05
③ 名前 :JapaneseServlet2
④ スーパークラス :javax.servlet.http.HttpServlet
⑤ アクセスURL :http://localhost:8080/web_basic/JapaneseServlet2
package ch05; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class JapaneseServlet2 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //コンテンツタイプの指定 response.setContentType("text/html; charset=UTF-8"); PrintWriter out = response.getWriter(); out.println("日本語を表示するServlet!"); } }➢ web.xml
<servlet> <servlet-name>JapaneseServlet2Mapping</servlet-name> <servlet-class>ch05.JapaneseServlet2</servlet-class> </servlet> <servlet-mapping> <servlet-name>JapaneseServlet2Mapping</servlet-name> <url-pattern>/JapaneseServlet2</url-pattern> </servlet-mapping>
解説
このサーブレットは「JapaneseServlet1」に13行目の記述を追加したプログラムです。それ以外の処理については全く同じ内容です。
13行目では、コンテンツタイプの指定を行っています。
今回のプログラムでは以下のような設定を宣言しています。
・ MIMEタイプ:text/html
・ 文字エンコーディング:charset=UTF-8
サーブレットは最終的にHTMLに変換されてブラウザに表示されるため、MIMEタイプは「text/html」となり、文字エンコーディングは日本語に対応した「charset=UTF-8」を設定しています。
実行結果からもわかるように、コンテンツタイプに日本語に対応した文字エンコーディングを記述したことで、「???????」と表示されていた日本語部分が正しく表示されるようになりました。
コンテンツタイプの指定はそのファイル全体の設定となるので、他の処理が行われる前の処理の一番初めに定義するようにしましょう。