2

私たちが構築している製品の要件は、その URL エンドポイントが母国語のユーザーにとって意味的に意味のあるものであることです。これは、太陽の下ですべてのアルファベットをサポートするには、UTF-8 でエンコードされた URL が必要であることを意味します。

また、サポートするすべてのアプリケーション サーバーとバージョンのインストール構成ドキュメントを提供する必要もありません。そのため、これをコード内で実行できればよいでしょう。サーブレットがリクエストを受信するまでに、アプリサーバーなどによってエンコードされているため、これは不可能な場合があります.

リクエストのパス情報を次のように再構成することで、これを機能させました(ISO-Latinの非US ASCII文字を使用した最初のユースケースの場合)。

String pathInfoEncoded = new String(httpServletRequest.getPathInfo().getBytes(), "UTF-8");

そしてそれを解析します。

ただし、sendRedirect() を使用して POST から GET にリダイレクトした後は、これは機能しません。リクエストのパスは既にエスケープされているため (ö は %F6 としてエンコードされます)、上記の方法は機能しません。

だから私の質問は、私はこれについてすべて間違っているのでしょうか? もしそうなら、私の無知に対する解毒剤は何ですか?:)

更新:解決策が見つかりました。問題は、サーブレット API が、リダイレクトを送信する前の URL エンコーディングに関して奇妙な動作をすることです。sendRedirect() を呼び出す前に、URL エンコード (UTF-8 文字をエスケープ) する必要があります。encodeRedirectURL() メソッドはそれを行いません。

このページで説明しています: http://www.whirlycott.com/phil/2005/05/11/building-j2ee-web-applications-with-utf-8-support/

4

3 に答える 3

4

調査して実験するいくつかのこと:

  • ./conf/server.xml ファイルを見て、コネクタの URIEncoding 属性が「UTF-8」に設定されていることを確認してください。

例えば:

<Connector port="8080" 
           protocol="HTTP/1.1" 
           URIEncoding="UTF-8"/>
  • ある種のブラウザベースのツール (例: FireFox のTamperData ) を使用して、ブラウザがサーバーに送信しているものを確認します。この場合、サーバーでURL.decode()を使用できます。
  • Response.redirect() を使用する代わりに、ヘッダーと応答コードを手動で設定します。

例えば:

response.setHeader("Location", myUtf8unencodedUrl);
response.setStatus(response.SC_MOVED_TEMPORARILY);

約束はできませんが、これは私だったら試してみたいものです。:)

于 2009-05-11T08:12:36.510 に答える
2

解決策を見つけました。問題は、サーブレット API が、リダイレクトを送信する前の URL エンコーディングに関して奇妙な動作をすることです。sendRedirect() を呼び出す前に、URL エンコード (UTF-8 文字をエスケープ) する必要があります。encodeRedirectURL() メソッドはそれを行いません。

このページで説明しています: http://www.whirlycott.com/phil/2005/05/11/building-j2ee-web-applications-with-utf-8-support/

于 2009-05-11T23:46:30.507 に答える
1

ここでも同じ状況があります。つまり、私たちの製品も意味のある URL を地球上のすべての言語でユーザーに表示する必要があります。すべてのツールとテクニックは UTF-8 をサポートしているため、問題ありません。UTF-8 文字のエスケープは技術的には機能しますが、IE (7, 8) は見苦しいエスケープされた URL を表示しますが、Firefox はエスケープを解除して適切な URL を表示します。つまり、'/français/Banane.html' は '/fran% C3%A7ais/Banane.html'. POST 後の GET / フォーム送信後のリダイレクトがまったく機能せず、UTF-8 URL の送信もエスケープされた UTF-8 URL の送信も行われませんでした。また、XML スタイルの数値エンティティ コーディングを使用しようとしましたが、成功しませんでした。

しかし、最終的に、POST の後に正常にリダイレクトする方法を見つけました。それは、ISO-8859-1 を使用してバイト単位で UTF-8 文字列をエンコードすることです。とにかく、これがどのように機能するかを本当に理解している人はいません(utf-8文字ごとのバイト数が異なる可能性があるため、ブラウザーはそれをデコードする方法をどのように知ることができ、ブラウザーは元がutf-8であったかをどのように知ることができますか?)します。

これを試すための簡単なサーブレットを次に示します。


package springapp.web.servlet;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;

public class TestServlet extends HttpServlet {

 private static final long serialVersionUID = -1743198460341004958L;

 /* (non-Javadoc)
  * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
  */
 @Override
 protected void doGet(HttpServletRequest req, HttpServletResponse resp)
   throws ServletException, IOException {

  String url = "çöffte.html"; 
  try {
         ServletContext context = req.getSession().getServletContext();
   // read utf8 encoded russian url
            if (context.getResource("/WEB-INF/ru_url.txt") != null){
             InputStream is = context.getResourceAsStream("/WEB-INF/ru_url.txt"); 
             if (is != null){
              url = IOUtils.toString(is, "UTF-8");
              System.out.println(String.format("Redirecting to [%s]", url));
             }
            }
        }
        catch (FileNotFoundException fNFEx) {
         fNFEx.printStackTrace();
        }
        catch (IOException ioEx) {
         ioEx.printStackTrace();
        }

        byte[] utfBytes = url.getBytes("UTF-8");
        String result = new String(utfBytes, "ISO-8859-1");
        resp.sendRedirect(result);

        // does not work:
        //resp.sendRedirect(url);
        //resp.sendRedirect(Utf8UrlEscaper.escapeUtf8(url));
        //resp.sendRedirect(Utf8UrlEscaper.escapeToNumericEntity(url));
 }
}

リダイレクト ターゲットの場合は、たとえばウィキペディアから utf-8 でエンコードされた (BOM なしの) ファイルにネイティブ言語の URL をコピー アンド ペーストし、それを WEB-INF ディレクトリに保存します。この例では、ロシア語の URL ( http://ru.wikipedia.org/wiki/Заглавная_страница ) を取得し、「ru_url.txt」という名前のファイルに保存します。

任意の *.abc URL をテスト サーブレットにマッピングする単純な SpringMVC アプリケーションを作成しました。ここで、アプリを起動して「localhost:8080/springmvctest/a.abc」のようなものを入力すると、ロシア語のウィキペディア サイトにリダイレクトされ、ブラウザー (IE と Firefox、Safari など) に適切な utf- が表示されるはずです。 8 エンコードされたネイティブ russion URL。

于 2009-09-17T13:39:31.530 に答える