Java WebアプリケーションでUTF-8を動作させるにはどうすればいいですか? 質問する

Java WebアプリケーションでUTF-8を動作させるにはどうすればいいですか? 質問する

äöå通常のフィンランド語のテキストや、特殊なケースのようなキリル文字のアルファベットなどをサポートするには、Java Web アプリケーション (サーブレット + JSP、フレームワークは使用しない) で UTF-8 を動作させる必要がЦжФあります。

私の設定は次のとおりです:

  • 開発環境: Windows XP
  • 運用環境: Debian

使用データベース: MySQL 5.x

ユーザーは主に Firefox2 を使用しますが、Opera 9.x、FF3、IE7、Google Chrome もサイトへのアクセスに使用されます。

これを実現するにはどうすればよいでしょうか?

ベストアンサー1

このサイトの FAQ として自分自身に答えることは、それを奨励します。これは私の場合はうまくいきます:

ブラウザや Web アプリケーションの Tomcat/Java で使用されるデフォルトの文字セットは latin1、つまり ISO-8859-1 であり、これらの文字を「理解」するため、ほとんどの場合、文字 äåö は問題になりません。

Java+Tomcat+Linux/Windows+Mysql で UTF-8 を動作させるには、次のものが必要です。

Tomcat の server.xml の設定

コネクタが UTF-8 を使用して URL (GET リクエスト) パラメータをエンコードするように構成する必要があります。

<Connector port="8080" maxHttpHeaderSize="8192"
 maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
 enableLookups="false" redirectPort="8443" acceptCount="100"
 connectionTimeout="20000" disableUploadTimeout="true" 
 compression="on" 
 compressionMinSize="128" 
 noCompressionUserAgents="gozilla, traviata" 
 compressableMimeType="text/html,text/xml,text/plain,text/css,text/ javascript,application/x-javascript,application/javascript"
 URIEncoding="UTF-8"
/>

上記の例の重要な部分はURIEncoding="UTF-8"です。これにより、Tomcat は受信したすべての GET パラメータを UTF-8 エンコードとして処理することが保証されます。その結果、ユーザーがブラウザのアドレス バーに次のように入力すると、

 https://localhost:8443/ID/Users?action=search&name=*ж*

文字 ж は UTF-8 として処理され、(通常はサーバーに到達する前にブラウザによって) %D0%B6にエンコードされます。

POST リクエストはこれの影響を受けません。

文字セットフィルター

次に、Java Web アプリケーションがすべてのリクエストと応答を UTF-8 エンコードで処理するように強制します。そのためには、次のような文字セット フィルターを定義する必要があります。

package fi.foo.filters;

import javax.servlet.*;
import java.io.IOException;

public class CharsetFilter implements Filter {

    private String encoding;

    public void init(FilterConfig config) throws ServletException {
        encoding = config.getInitParameter("requestEncoding");
        if (encoding == null) encoding = "UTF-8";
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain next)
            throws IOException, ServletException {
        // Respect the client-specified character encoding
        // (see HTTP specification section 3.4.1)
        if (null == request.getCharacterEncoding()) {
            request.setCharacterEncoding(encoding);
        }

        // Set the default response content type and encoding
        response.setContentType("text/html; charset=UTF-8");
        response.setCharacterEncoding("UTF-8");

        next.doFilter(request, response);
    }

    public void destroy() {
    }
}

このフィルターは、ブラウザがリクエストで使用されるエンコードを設定していない場合に、それが UTF-8 に設定されていることを確認します。

このフィルターによって行われるもう 1 つのことは、デフォルトの応答エンコーディング、つまり返される HTML などのエンコーディングを設定することです。別の方法としては、アプリケーションの各コントローラーで応答エンコーディングなどを設定する方法があります。

このフィルターは、 web.xmlまたは Web アプリケーションのデプロイメント記述子に追加する必要があります。

 <!--CharsetFilter start--> 

  <filter>
    <filter-name>CharsetFilter</filter-name>
    <filter-class>fi.foo.filters.CharsetFilter</filter-class>
      <init-param>
        <param-name>requestEncoding</param-name>
        <param-value>UTF-8</param-value>
      </init-param>
  </filter>

  <filter-mapping>
    <filter-name>CharsetFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

このフィルターの作り方は、トムキャットウィキ (http://wiki.apache.org/tomcat/Tomcat/UTF-8

JSP ページエンコーディング

web.xmlに次のコードを追加します。

<jsp-config>
    <jsp-property-group>
        <url-pattern>*.jsp</url-pattern>
        <page-encoding>UTF-8</page-encoding>
    </jsp-property-group>
</jsp-config>

あるいは、Web アプリケーションのすべての JSP ページの先頭に次の内容を含める必要があります。

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

異なる JSP フラグメントを含む何らかのレイアウトを使用する場合は、それらすべてにこれが必要です。

HTMLメタタグ

JSP ページ エンコーディングは、JSP ページ内の文字を正しいエンコーディングで処理するように JVM に指示します。次に、HTML ページのエンコーディングをブラウザに指示します。

これは、Web アプリケーションによって生成される各 xhtml ページの上部に次のコードを追加することで実行されます。

   <?xml version="1.0" encoding="UTF-8"?>
   <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
   <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fi">
   <head>
   <meta http-equiv='Content-Type' content='text/html; charset=UTF-8' />
   ...

JDBC接続

データベースを使用する場合、接続で UTF-8 エンコーディングを使用するように定義する必要があります。これは、context.xmlまたは JDBC 接続が定義されている場所で次のように実行されます。

      <Resource name="jdbc/AppDB" 
        auth="Container"
        type="javax.sql.DataSource"
        maxActive="20" maxIdle="10" maxWait="10000"
        username="foo"
        password="bar"
        driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/      ID_development?useEncoding=true&amp;characterEncoding=UTF-8"
    />

MySQL データベースとテーブル

使用するデータベースは UTF-8 エンコードを使用する必要があります。これは、次のようにデータベースを作成することで実現されます。

   CREATE DATABASE `ID_development` 
   /*!40100 DEFAULT CHARACTER SET utf8 COLLATE utf8_swedish_ci */;

次に、すべてのテーブルも UTF-8 である必要があります。

   CREATE TABLE  `Users` (
    `id` int(10) unsigned NOT NULL auto_increment,
    `name` varchar(30) collate utf8_swedish_ci default NULL
    PRIMARY KEY  (`id`)
   ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_swedish_ci ROW_FORMAT=DYNAMIC;

重要な部分はCHARSET=utf8です。

MySQLサーバーの構成

MySQL serveri も設​​定する必要があります。通常、これは Windows ではmy.iniファイルを変更して、Linux ではmy.cnfファイルを設定することで行われます。これらのファイルでは、サーバーに接続するすべてのクライアントがデフォルトの文字セットとして utf8 を使用し、サーバーが使用するデフォルトの文字セットも utf8 になるように定義する必要があります。

   [client]
   port=3306
   default-character-set=utf8

   [mysql]
   default-character-set=utf8

MySQL のプロシージャと関数

これらにも文字セットを定義する必要があります。例:

   DELIMITER $$

   DROP FUNCTION IF EXISTS `pathToNode` $$
   CREATE FUNCTION `pathToNode` (ryhma_id INT) RETURNS TEXT CHARACTER SET utf8
   READS SQL DATA
   BEGIN

    DECLARE path VARCHAR(255) CHARACTER SET utf8;

   SET path = NULL;

   ...

   RETURN path;

   END $$

   DELIMITER ;

GET リクエスト: latin1 および UTF-8

Tomcat の server.xml で GET 要求パラメータが UTF-8 でエンコードされるように定義されている場合、次の GET 要求は適切に処理されます。

   https://localhost:8443/ID/Users?action=search&name=Petteri
   https://localhost:8443/ID/Users?action=search&name=ж

ASCII 文字は latin1 と UTF-8 の両方で同じようにエンコードされるため、文字列「Petteri」は正しく処理されます。

キリル文字 ж は、latin1 ではまったく認識されません。Tomcat はリクエスト パラメータを UTF-8 として処理するように指示されているため、その文字は%D0%B6として正しくエンコードされます。

ブラウザが UTF-8 エンコード (リクエスト ヘッダーと HTML メタ タグ付き) でページを読み取るように指示されている場合、少なくとも Firefox 2/3 およびこの時期の他のブラウザはすべて、文字自体を%D0%B6としてエンコードします。

最終結果として、「Petteri」という名前のすべてのユーザーが検索され、「ж」という名前のすべてのユーザーも検索されます。

しかし、äåö はどうでしょうか?

HTTP仕様では、URLはデフォルトでlatin1でエンコードされることが定義されています。これにより、firefox2、firefox3などで次のエンコードが行われます。

    https://localhost:8443/ID/Users?action=search&name=*Päivi*

エンコードされたバージョンに

    https://localhost:8443/ID/Users?action=search&name=*P%E4ivi*

latin1 では、文字äは%E4としてエンコードされます。ページ/リクエスト/すべてが UTF-8 を使用するように定義されているにもかかわらず、UTF-8 でエンコードされた ä のバージョンは%C3%A4です。

その結果、一部の文字はlatin1でエンコードされ、他の文字はUTF-8でエンコードされるため、ウェブアプリケーションがGETリクエストからのリクエストパラメータを正しく処理することは不可能になります。注意:ページがUTF-8として定義されている場合、ブラウザはフォームからのすべてのリクエストパラメータを完全にUTF-8でエンコードするため、POSTリクエストは機能します。

読むべきもの

私の問題に対する答えを提供してくれた以下の著者の方々に心から感謝します。

  • http://tagunov.tripod.com/i18n/i18n.html
  • http://wiki.apache.org/tomcat/Tomcat/UTF-8
  • http://java.sun.com/developer/technicalArticles/Intl/HTTPCharset/
  • http://dev.mysql.com/doc/refman/5.0/en/charset-syntax.html
  • http://cagan327.blogspot.com/2006/05/utf-8-encoding-fix-tomcat-jsp-etc.html
  • http://cagan327.blogspot.com/2006/05/utf-8-encoding-fix-for-mysql-tomcat.html
  • 翻訳元:
  • http://www.nabble.com/request-parameters-mishandle-utf-8-encoding-td18720039.html
  • http://www.utoronto.ca/webdocs/HTMLdocs/NewHTML/iso_table.html
  • http://www.utf8-chartable.de/

重要な注意点

をサポートする基本的な多言語面3バイトのUTF-8文字を使用します。それ以外の文字(特定のアルファベットでは3バイト以上のUTF-8文字が必要)が必要な場合は、VARBINARY列タイプのフレーバーを使用するか、utf8mb4キャラクターセット(MySQL 5.5.3 以降が必要です)。MySQLutf8の文字セットを使用すると、100% 機能するとは限らないことに注意してください。

Tomcat と Apache

さらに、Apache + Tomcat + mod_JK コネクタを使用している場合は、次の変更も行う必要があります。

  1. 8009 コネクタの tomcat server.xml ファイルに URIEncoding="UTF-8" を追加します。これは mod_JK コネクタによって使用されます。<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" URIEncoding="UTF-8"/>
  2. Apache フォルダー (ie) に移動して/etc/httpd/conf、 を追加しますAddDefaultCharset utf-8httpd.conf file:まず、存在するかどうかを確認します。存在する場合は、この行で更新できます。この行を下部に追加することもできます。

おすすめ記事