Javaでサーブレットフィルターを使用して、受信するサーブレットリクエストのURLを変更する方法


186

サーブレットフィルターを使用して受信サーブレットリクエストのURLを変更するにはどうすればよいですか

http://nm-java.appspot.com/Check_License/Dir_My_App/Dir_ABC/My_Obj_123

http://nm-java.appspot.com/Check_License?Contact_Id=My_Obj_123


更新:以下のBalusCの手順に従って、私は次のコードを考え出しました:

public class UrlRewriteFilter implements Filter {

    @Override
    public void init(FilterConfig config) throws ServletException {
        //
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest) req;
        String requestURI = request.getRequestURI();

        if (requestURI.startsWith("/Check_License/Dir_My_App/")) {
            String toReplace = requestURI.substring(requestURI.indexOf("/Dir_My_App"), requestURI.lastIndexOf("/") + 1);
            String newURI = requestURI.replace(toReplace, "?Contact_Id=");
            req.getRequestDispatcher(newURI).forward(req, res);
        } else {
            chain.doFilter(req, res);
        }
    }

    @Override
    public void destroy() {
        //
    }
}

の関連エントリは次のweb.xmlようになります。

<filter>
    <filter-name>urlRewriteFilter</filter-name>
    <filter-class>com.example.UrlRewriteFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>urlRewriteFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

サーバー側とクライアント側の両方のリダイレクトを試しましたが、期待どおりの結果が得られました。BalusCに感謝します。



使用しているサーブレット仕様のバージョンは何ですか?リクエストを転送する方法は、バージョンによって異なります。
ロメインヒッポー


元のURLにパラメーター(nm-java.appspot.com/Check_License/Dir_My_App/Dir_ABC/My_Obj_123?** param1 = A&param2 = B **)が含まれている場合、これらのパラメーターも次のサーブレット/ jspに転送されることに注意してください。(HttpServletRequestWrapperを使用してのみ)元のパラメーターを削除または置き換える方法が見つかりませんでした。任意のアイデア?..更新:http : //ocpsoft.org/opensource/how-to-safely-add-modify-servlet-request-parameter-values/がこの問題に対処しているようです。
ロポトゥン

ありがとう、URLの書き換えと暗号化の例を探していました。
Aditya Yada

回答:


281
  1. 実装しjavax.servlet.Filterます。
  2. ではdoFilter()この方法は、着信キャストServletRequestにしますHttpServletRequest
  3. HttpServletRequest#getRequestURI()パスをつかむために使用します。
  4. 簡単な使用java.lang.Stringのようなメソッドsubstring()split()concat()興味の一部を抽出し、新しいパスを構成するというようにします。
  5. いずれかを使用ServletRequest#getRequestDispatcher()して、RequestDispatcher#forward()(ブラウザのアドレスバーに反映されていないサーバー側のリダイレクト、)新しいURLへのリクエスト/レスポンスを転送する、または、着信をキャストServletResponseHttpServletResponseた後とHttpServletResponse#sendRedirect()に反映新しいURL(クライアント側のリダイレクトに応答をリダイレクトしますブラウザのアドレスバー)。
  6. でフィルタを登録するweb.xmlurl-pattern/*/Check_License/*、コンテキストパスに応じて、または既にサーブレット3.0にしている場合は、使用し@WebFilterている代わりのための注釈を。

URL を変更する必要がある場合はコードにチェックを追加し、そうでない場合はを呼び出すだけFilterChain#doFilter()です。そうしないと、無限ループで自分自身を呼び出します。

あるいは、既存のサードパーティAPIを使用してすべての作業を行うこともできます。たとえば、Apacheの場合と同じように構成できるTuckeyのUrlRewriteFilterなどですmod_rewrite


1
上記を行うどこかにdoFilter()サンプルコードがありますか?ありがとう。
フランク

20
いったいどの段階で立ち往生していますか?私の答えはほとんどコード自体を書いています。また、青色のコード参照は、クラス/メソッドの動作を詳細に説明するJavadocへのリンクであることにも注意しましたか?どのような方法で、あなたは見つけることができるここここに良いJSP /サーブレットのチュートリアル、特にこのフィルタに関するものを。
BalusC 2010

1
私はそれは正しいと思いますが、フィルターがチェーンの最初の1つであり、RequestDispatcher#forward()実行された場合、残りのフィルターは実行されません。それで、これをサーブレットとして行うより良い方法はありませんか?
lucasvc 2014年

2
@datakey:順序を並べ替えるか、<dispatcher>FORWARD</dispatcher>フィルターマッピングに追加します。
BalusC 2014年

1
@ JimJim2000:順序を並べ替えるか、<dispatcher>FORWARD</dispatcher>フィルターマッピングに追加します。
BalusC 2016年


7

BalusCの回答のステップに基づく単純なJSF Url Prettyfierフィルター。フィルターは、/ uiパス(すべてのxhtmlファイルがそこに格納されていると想定)で始まるすべての要求を同じパスに転送しますが、xhtmlサフィックスを追加します。

public class UrlPrettyfierFilter implements Filter {

    private static final String JSF_VIEW_ROOT_PATH = "/ui";

    private static final String JSF_VIEW_SUFFIX = ".xhtml";

    @Override
    public void destroy() {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest httpServletRequest = ((HttpServletRequest) request);
        String requestURI = httpServletRequest.getRequestURI();
        //Only process the paths starting with /ui, so as other requests get unprocessed. 
        //You can register the filter itself for /ui/* only, too
        if (requestURI.startsWith(JSF_VIEW_ROOT_PATH) 
                && !requestURI.contains(JSF_VIEW_SUFFIX)) {
            request.getRequestDispatcher(requestURI.concat(JSF_VIEW_SUFFIX))
                .forward(request,response);
        } else {
            chain.doFilter(httpServletRequest, response);
        }
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {

    }

}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.