URLを完成させるためのHttpServletRequest


247

HttpServletRequestオブジェクトがあります。

この呼び出しがサーブレットに到達する原因となった完全で正確なURLを取得するにはどうすればよいですか?

または、少なくとも可能な限り正確に、おそらく再生成できるもの(おそらくパラメーターの順序)があります。



util関数を使用しなかった理由
vanduc1102

回答:


392

HttpServletRequest次のメソッドがあります。

  • getRequestURL() -クエリ文字列区切り文字の前に完全なURLの一部を返します ?
  • getQueryString() -クエリ文字列区切り文字の後の完全なURLの一部を返します ?

したがって、完全なURLを取得するには、次のようにします。

public static String getFullURL(HttpServletRequest request) {
    StringBuilder requestURL = new StringBuilder(request.getRequestURL().toString());
    String queryString = request.getQueryString();

    if (queryString == null) {
        return requestURL.toString();
    } else {
        return requestURL.append('?').append(queryString).toString();
    }
}

3
getRequestURIから説明をコピーしましたが(間違っています)、コードでgetRequestURLを使用しています(右)。
Vinko Vrsalovic、2010

21
クエリ文字列が空かどうかを条件付きでチェックする必要があります。
アダム・ゲント

8
また、リクエストURLをバッキングするStringBufferを変更します。リクエストの実装が防御的なコピーを作成していない場合は、奇妙な動作や、元の形式で予期されるコードの他の部分にバグを導入するのに非常に良い方法です。
ケン・ブレア

5
StringBufferの代わりにStringBuilderを使用する
Gladwin Burboz

17
@KenBlair:StringBufferが意図的に返されるため、より多くのスタッシュを簡単に追加できます。これはjavadocで指定されているので、返されたStringBufferが呼び出し元によって変更されないことを期待するのは実装が非常に馬鹿げているため、これはクールです。
stolsvik 2013

145

私はこの方法を使用します:

public static String getURL(HttpServletRequest req) {

    String scheme = req.getScheme();             // http
    String serverName = req.getServerName();     // hostname.com
    int serverPort = req.getServerPort();        // 80
    String contextPath = req.getContextPath();   // /mywebapp
    String servletPath = req.getServletPath();   // /servlet/MyServlet
    String pathInfo = req.getPathInfo();         // /a/b;c=123
    String queryString = req.getQueryString();          // d=789

    // Reconstruct original requesting URL
    StringBuilder url = new StringBuilder();
    url.append(scheme).append("://").append(serverName);

    if (serverPort != 80 && serverPort != 443) {
        url.append(":").append(serverPort);
    }

    url.append(contextPath).append(servletPath);

    if (pathInfo != null) {
        url.append(pathInfo);
    }
    if (queryString != null) {
        url.append("?").append(queryString);
    }
    return url.toString();
}

8
これは、HttpServletRequestで利用可能なすべての情報をすばやく参照するのに役立つ回答です。ただし、ポートピースを結果に追加するかどうかを決定する際には、スキームを確認する必要があると思います。たとえば、「https」は443です。
Peter Cardona 2012年

2
小さな最適化は、StringBufferの代わりにStringBuilderを使用することです。これは単なるヒントです
Chris

11
単なるコメント:この特定の例では、スレッドの安全性は問題ではありません。url宣言、インスタンス化、およびメソッド内でのみ使用されるため、メソッドを呼び出したスレッド以外のスレッドからはアクセスできません。
Diogo Kollross 14年

1
前述のように、StringBuffer呼び出しごとにインスタンスを作成し、他のスレッドと共有しないため、スレッドの安全性はここでは問題になりません。これをに変更する必要がありStringBuilderます。
グレイ

1
使用しない理由はgetRequestURI
Christophe Roussy

27
// http://hostname.com/mywebapp/servlet/MyServlet/a/b;c=123?d=789

public static String getUrl(HttpServletRequest req) {
    String reqUrl = req.getRequestURL().toString();
    String queryString = req.getQueryString();   // d=789
    if (queryString != null) {
        reqUrl += "?"+queryString;
    }
    return reqUrl;
}

5
あなたはの利点を無視していますStringBuffer
BalusC 2010

はい。私はそれを受け入れますが、私が推測する追加のオブジェクトは2つだけです。
Teja Kantamneni 2010

9
これは1つの追加オブジェクト(StringBuilder)であり、返される基になるStringBufferを変更しません。私は実際には「受け入れられた」答えよりもこれを好みます。JVMはその違いに関係なく最適化し、バグを導入するリスクはありません。
ケン・ブレア

(request.getRequestURL()。toString()+((request.getQueryString()!= null)?( "?" + request.getQueryString()): ""))
Alex


6

HttpUtilは廃止予定です。これは正しい方法です

StringBuffer url = req.getRequestURL();
String queryString = req.getQueryString();
if (queryString != null) {
    url.append('?');
    url.append(queryString);
}
String requestURL = url.toString();


1

フィルターを使用できます。

@Override
    public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException {
            HttpServletRequest test1=    (HttpServletRequest) arg0;

         test1.getRequestURL()); it gives  http://localhost:8081/applicationName/menu/index.action
         test1.getRequestURI()); it gives applicationName/menu/index.action
         String pathname = test1.getServletPath()); it gives //menu/index.action


        if(pathname.equals("//menu/index.action")){ 
            arg2.doFilter(arg0, arg1); // call to urs servlet or frameowrk managed controller method


            // in resposne 
           HttpServletResponse httpResp = (HttpServletResponse) arg1;
           RequestDispatcher rd = arg0.getRequestDispatcher("another.jsp");     
           rd.forward(arg0, arg1);





    }

<dispatcher>FORWARD</dispatcher>web.xmlにフィルターマッピングを含めることを忘れないでください。


レコードについて... test1.getRequestURI()); /applicationName/menu/index.action(つまり、先頭にスラッシュが含まれています)
Stevko

1

HttpServletRequestオブジェクトで次のメソッドを使用します

java.lang.String getRequestURI() -プロトコル名からHTTPリクエストの最初の行のクエリ文字列まで、このリクエストのURLの一部を返します。

java.lang.StringBuffer getRequestURL() -クライアントがリクエストを行うために使用したURLを再構築します。

java.lang.String getQueryString() -パスの後にリクエストURLに含まれるクエリ文字列を返します。


0

パーティーには多少遅れましたが、これをWebUtilsのMarkUtils-Webライブラリ含めました-Checkstyle承認およびJUnitテスト済み:

import javax.servlet.http.HttpServletRequest;

public class GetRequestUrl{
    /**
     * <p>A faster replacement for {@link HttpServletRequest#getRequestURL()}
     *  (returns a {@link String} instead of a {@link StringBuffer} - and internally uses a {@link StringBuilder})
     *  that also includes the {@linkplain HttpServletRequest#getQueryString() query string}.</p>
     * <p><a href="https://gist.github.com/ziesemer/700376d8da8c60585438"
     *  >https://gist.github.com/ziesemer/700376d8da8c60585438</a></p>
     * @author Mark A. Ziesemer
     *  <a href="http://www.ziesemer.com.">&lt;www.ziesemer.com&gt;</a>
     */
    public String getRequestUrl(final HttpServletRequest req){
        final String scheme = req.getScheme();
        final int port = req.getServerPort();
        final StringBuilder url = new StringBuilder(256);
        url.append(scheme);
        url.append("://");
        url.append(req.getServerName());
        if(!(("http".equals(scheme) && (port == 0 || port == 80))
                || ("https".equals(scheme) && port == 443))){
            url.append(':');
            url.append(port);
        }
        url.append(req.getRequestURI());
        final String qs = req.getQueryString();
        if(qs != null){
            url.append('?');
            url.append(qs);
        }
        final String result = url.toString();
        return result;
    }
}

おそらくここでMat Banikの背後にある最も高速で最も堅牢な答えですが、彼も、HTTP / HTTPSでの非標準のポート構成の可能性を考慮していません。

以下も参照してください。


0

3値を使用して単純な1ライナーを記述できます。StringBufferのビルダーパターンを使用する場合は、次のようになります.getRequestURL()

private String getUrlWithQueryParms(final HttpServletRequest request) { 
    return request.getQueryString() == null ? request.getRequestURL().toString() :
        request.getRequestURL().append("?").append(request.getQueryString()).toString();
}

しかし、それは単なる構文上の砂糖です。

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