Java 全般

Webブラウザが文字コードを判定する基準のメモです

@IT Javaの文字化け対策FAQ(1)を参考にしました

Webブラウザが文字コードを判定する基準

HTML4.01の仕様では、ブラウザが以下の優先順位で文字コードを決定する事を規定しているそうです

  1. HTTPにおけるContent-Typeヘッダのcharsetパラメータ
  2. HTML文書内のMETA宣言およびhttp-equiv属性で設定された、Content-Typeヘッダのcharsetパラメータ
  3. HTML文書内の各要素のcharset属性

以下の様なJSPを実行した場合、

<%@ page language="java" %>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
 テストページ
</body>
</html>

TomcatはContent-Typeヘッダにデフォルトの文字コードであるISO-8859-1を指定するため、META宣言よりもContent-Typeヘッダが優先されてしまい、文字化けを起こします

こうしたトラブルを避ける為

JSPの場合

pageディレクティブで文字コードを指定する

Servletの場合

HttpServletResponse.setContentTypeメソッドで文字コードを指定する

これを行えば、META宣言は不要です

具体的には・・・

JSPの場合

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

   contentType属性 :JSPファイル出力時の文字コード、およびContent-Typeヘッダに出力する文字コード名を指定する
   pageEncoding属性:JSPファイル作成時の文字コードを指定する

contentType属性

「JSPファイル出力時の文字コード」と「Content-Typeヘッダに指定する文字コード」の両方を指定するという働きを持つ

上記例のように記述すれば、サーブレット・コンテナはコンテンツをWindows-31Jにエンコードして出力する

また同時に、Content-Type ヘッダを通じて文字コード種別をWebブラウザに伝達する

pageEncoding属性の役割

「JSPファイル作成時の文字コード」を指定するための属性であり、 JSP 1.2仕様(Tomcat 4.0)以降からサポートされている

pageEncoding 属性を省略した場合、JSP 1.2仕様では「contentType属性で指定された文字コードでJSPファイルを読み込む」

と規定されている

よって通常は省略しても文字化けが発生する恐れはない

またインクルードされるJSPファイルではcontentType属性を記述できないため、 pageEncoding属性の利用が必須となる

servletの場合

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

ただし、ApacheとTomcatを連携している場合、apacheの設定ファイルでAddDefaultCharset ISO-8859-1が指定されているとそちらが優先されるので、この設定をapache側では行わない様にする事が必要です

関連ページ