375

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

私のセットアップは次のとおりです。

  • 開発環境:Windows XP
  • 本番環境:Debian

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

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

これを達成する方法は?

4

14 に答える 14

562

このサイトの FAQ として自分自身に答えると、それが促進されます。これは私にとってはうまくいきます:

ブラウザで使用されるデフォルトの文字セットと webapps の 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または webapp の配置記述子に追加する必要があります。

 <!--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>

このフィルターを作成する手順は、Tomcat wiki ( 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>

あるいは、webapp のすべての JSP ページの上部に次の内容を含める必要があります。

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

異なる JSP フラグメントを持つある種のレイアウトが使用されている場合、これはすべてのフラグメントで必要になります。

HTML メタタグ

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

これは、webapp によって生成される各 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 サーバーも構成する必要があります。通常、これは、Windows ではmy.ini -file を変更することによって行われ、Linux では my.cnf -file を構成することによって行われます。これらのファイルでは、サーバーに接続されているすべてのクライアントがデフォルトの文字セットとして 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 でエンコードされるため、webapp が 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://jeppesn.dk/utf-8.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 文字を使用するBasic Multilingual Planeをサポートしています。それ以外に移動する必要がある場合 (特定のアルファベットには 3 バイト以上の UTF-8 が必要です)、VARBINARY列タイプのフレーバーを使用するか、utf8mb4文字セットを使用する必要があります (これには MySQL 5.5.3 以降が必要です)。utf8MySQL の文字セットを使用しても 100% うまくいかないことに注意してください。

Tomcat と Apache

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

  1. URIEncoding="UTF-8" を 8009 コネクタの tomcat server.xml ファイルに追加します。これは mod_JK コネクタで使用されます。<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" URIEncoding="UTF-8"/>
  2. apache フォルダー/etc/httpd/confに移動AddDefaultCharset utf-8し、httpd.conf file. 注:最初に存在するかどうかを確認してください。存在する場合は、この行で更新できます。この行を一番下にも追加できます。
于 2008-09-26T11:48:24.787 に答える
14

あなた自身の答えでそれを非常にうまく要約したと思います。

エンドツーエンドで UTF-8-ing(?) を実行する過程で、Java 自体が UTF-8 を使用していることを確認することもできます。-Dfile.encoding=utf-8 を JVM へのパラメーターとして使用します (catalina.bat で構成できます)。

于 2008-09-27T21:54:08.160 に答える
12

kosoant の回答に追加するには、Spring を使用している場合、独自のサーブレット フィルターを作成するのではなく、org.springframework.web.filter.CharacterEncodingFilter提供されるクラスを使用して、web.xml で次のように構成できます。

 <filter>
    <filter-name>encoding-filter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
       <param-name>encoding</param-name>
       <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
       <param-name>forceEncoding</param-name>
       <param-value>FALSE</param-value>
    </init-param>
 </filter>
 <filter-mapping>
    <filter-name>encoding-filter</filter-name>
    <url-pattern>/*</url-pattern>
 </filter-mapping>
于 2014-01-28T15:10:17.330 に答える
2

ここから追加したいのは、この部分がutfの問題を解決したことです。

runtime.encoding=<encoding>
于 2010-05-13T16:47:34.397 に答える
1

これは、Javaを使用してMySqlテーブルにアクセスする場合のギリシャ語エンコーディング用です。

JBoss接続プール(mysql-ds.xml)で次の接続設定を使用します

<connection-url>jdbc:mysql://192.168.10.123:3308/mydatabase</connection-url>
<driver-class>com.mysql.jdbc.Driver</driver-class>
<user-name>nts</user-name>
<password>xaxaxa!</password>
<connection-property name="useUnicode">true</connection-property>
<connection-property name="characterEncoding">greek</connection-property>

これをJNDI接続プールに入れたくない場合は、次の行に示すように、JDBC-urlとして構成できます。

jdbc:mysql://192.168.10.123:3308/mydatabase?characterEncoding=greek

私とニックにとって、私たちはそれを決して忘れず、もう時間を無駄にしません.....

于 2009-12-04T13:52:33.223 に答える
1

素敵な詳細な答え。URL の UTF-8 エンコーディングが実際に動作していることを他の人が確認するのに確実に役立つものをもう 1 つ追加したかっただけです。

次の手順に従って、Firefox の URL で UTF-8 エンコーディングを有効にします。

  1. アドレスバーに「about:config」と入力します。

  2. フィルター入力タイプを使用して、「network.standard-url.encode-query-utf8」プロパティを検索します。

  3. 上記のプロパティはデフォルトで false になるため、TRUE に変更します。
  4. ブラウザを再起動します。

URL の UTF-8 エンコーディングは、デフォルトで IE6/7/8 および chrome で機能します。

于 2010-02-19T01:30:34.160 に答える
0

私は同様の問題を抱えていますが、ファイルのファイル名では、Apache Commons で圧縮しています。だから、私はこのコマンドでそれを解決しました:

convmv --notest -f cp1252 -t utf8 * -r

それは私にとって非常にうまく機能します。それが誰かを助けることを願っています;)

于 2011-07-20T13:45:30.053 に答える
0

CharsetFilter@kosoantの回答に記載されていることについて....

FilterTomcatには組み込みがありますweb.xml( にありますconf/web.xml)。フィルタには名前が付けられsetCharacterEncodingFilter、デフォルトでコメントが付けられます。これのコメントを外すことができます (これも忘れずにコメントを外してくださいfilter-mapping)

jsp-configまた、設定する必要はありませんweb.xml(Tomcat 7+でテストしました)

于 2017-01-09T05:24:48.103 に答える
0

言及されていないもう 1 つのポイントは、Ajax で動作する Java サーブレットに関連しています。Web ページが、サーブレットに送信される URI に含まれる JavaScript ファイルにこれを送信するユーザーから utf-8 テキストを取得している状況があります。サーブレットはデータベースにクエリを実行し、結果をキャプチャして XML として JavaScript ファイルに返します。JavaScript ファイルはそれをフォーマットし、フォーマットされた応答を元の Web ページに挿入します。

ある Web アプリでは、初期の Ajax の本の指示に従って、URI を構築する JavaScript をラップしていました。本の例では escape() メソッドを使用していましたが、これは (難しい方法で) 間違っていることがわかりました。utf-8 の場合は、encodeURIComponent() を使用する必要があります。

最近では、独自の Ajax を作成する人はほとんどいないようですが、これを追加したほうがよいと思いました。

于 2015-11-14T22:30:51.480 に答える
0

メッセージ バンドルから Unicode 文字を表示する場合、jsp ページに Unicode を表示するために「JSP ページ エンコーディング」セクションを適用する必要はありません。必要なのは「CharsetFilter」セクションだけです。

于 2012-06-21T01:59:03.767 に答える
-1

接続プール(mysql-ds.xml)で指定した場合、Javaコードで次のように接続を開くことができます。

DriverManager.registerDriver(new com.mysql.jdbc.Driver());
Connection conn = DriverManager.getConnection(
    "jdbc:mysql://192.168.1.12:3308/mydb?characterEncoding=greek",
    "Myuser", "mypass");
于 2009-12-11T17:12:08.067 に答える