HttpServletRequestのgetRequestURIメソッドとgetPathInfoメソッドの違いは何ですか?


143

シンプルで非常に軽量なフロントコントローラーを作っています。正しいハンドラーを選択するには、リクエストパスを別のハンドラー(アクション)に一致させる必要があります。

私のローカルマシンHttpServletRequest.getPathInfo()HttpServletRequest.getRequestURI()同じ結果を返します。しかし、私は彼らが本番環境で何を返すのかわかりません。

では、これらの方法と何を選択すればよいのですか?


1
あなたは見つけることがあり、この答えは同様に有用です。
BalusC、2011

@BalusC:ありがとう、私はすでにその回答からいくつかのヒントを使用しています。
ローマ

これは素敵な図との違いを説明していますagiletribe.wordpress.com/2016/02/23/...
AgilePro

回答:


77

getPathInfo()サーブレットへのアクセスに使用されるURIの後に追加のパス情報を提供しますgetRequestURI()。ここで、as は完全なURIを提供します。

そもそもサーブレットを独自のURIパターンで構成する必要があることを考えると、それらは異なるものだと思っていたでしょう。ルート(/)からサーブレットを提供したことがないと思います。

たとえば、サーブレット 'Foo'がURI '/ foo'にマップされている場合、私はそのURIを考えていました。

/foo/path/to/resource

結果として:

RequestURI = /foo/path/to/resource

そして

PathInfo = /path/to/resource

20
デコード動作について言及する価値があります。getRequestURI()は文字列をデコードしません。getPathInfo()がデコードする場所。
Kavindu Dodanduwa 16

1
場合によってgetRequestURI()"/foo/path/to/resource"、期待どおりの文字列が得られますがgetPathInfo()、同じHttpServletRequestオブジェクトに対してが得られますnull。世界で何が起こっているのですか?編集:それは、ユーザー「30thh」によって以下で答えられます。
anddero

460

ここに小さな比較表を置きます(どこかに置くためです):

サーブレットはとしてマップされ/test%3F/*、アプリケーションはの下にデプロイされ/appます。

http://30thh.loc:8480/app/test%3F/a%3F+b;jsessionid=S%3F+ID?p+1=c+d&p+2=e+f#a

Method              URL-Decoded Result           
----------------------------------------------------
getContextPath()        no      /app
getLocalAddr()                  127.0.0.1
getLocalName()                  30thh.loc
getLocalPort()                  8480
getMethod()                     GET
getPathInfo()           yes     /a?+b
getProtocol()                   HTTP/1.1
getQueryString()        no      p+1=c+d&p+2=e+f
getRequestedSessionId() no      S%3F+ID
getRequestURI()         no      /app/test%3F/a%3F+b;jsessionid=S+ID
getRequestURL()         no      http://30thh.loc:8480/app/test%3F/a%3F+b;jsessionid=S+ID
getScheme()                     http
getServerName()                 30thh.loc
getServerPort()                 8480
getServletPath()        yes     /test?
getParameterNames()     yes     [p 2, p 1]
getParameter("p 1")     yes     c d

上記の例では、サーバーはで実行されてlocalhost:8480おり、名前30thh.locはOS hostsファイルに入力されています。

コメント

  • 「+」はクエリ文字列でのみスペースとして処理されます

  • アンカー「#a」はサーバーに転送されません。ブラウザでのみ動作します。

  • url-patternサーブレットマッピングがで終わっていない場合*/testまたはなど*.jsp)、をgetPathInfo()返しますnull

Spring MVCを使用する場合

  • メソッドgetPathInfo()はを返しますnull

  • メソッドgetServletPath()は、コンテキストパスとセッションIDの間の部分を返します。上記の例では、値は/test?/a?+b

  • URLエンコードされた部分には注意してください@RequestMapping@RequestParam春インチ バグがあり(現在のバージョン3.2.4)、通常は期待どおりに動作しません


20
私はあなたの答えを印刷して、私たちのオフィスにポスターとして載せます。それはとても便利です!
イブラヒムArief

2
If the url-pattern in the servlet mapping does not end with * (for example /test or *.jsp), getPathInfo() returns null.鮮やかさ。
ボリストロイホフ2016年

1
私は両方を信じてgetRequestURI()おりgetRequestURL()、この場合はデコードされていないjsessionidを返す必要がありS%3F+IDます。少なくとも、Tomcat / 8.5.6では実行されます。
ゲディミナスリムサ2017年

29

クライアントがアドレスバーに入力してサーブレットにアクセスするための完全なURLを分解してみましょう。

http://www.example.com:80/awesome-application/path/to/servlet/path/info?a=1&b=2#boo

パーツは次のとおりです。

  1. スキーム: http
  2. ホスト名: www.example.com
  3. 港: 80
  4. コンテキストパス: awesome-application
  5. サーブレットのパス: path/to/servlet
  6. パス情報: path/info
  7. クエリ: a=1&b=2
  8. 断片: boo

リクエストURI(getRequestURIによって返される)は、パート4、5、および6に対応します。

(偶然にも、これを要求していなくても、メソッドgetRequestURLはパート1、2、3、4、5、6を提供します)。

今:

  • パート4(コンテキストパス)は、サーバーで実行されている他の多くのアプリケーションから特定のアプリケーションを選択するために使用されます
  • パート5(サーブレットパス)は、アプリケーションのWARにバンドルされている可能性のある他の多くのサーブレットから特定のサーブレットを選択するために使用されます
  • パート6(パス情報)は、サーブレットのロジックによって解釈されます(たとえば、サーブレットによって制御されるリソースを指す場合があります)。
  • パート7(クエリ)も、getQueryStringを使用してサーブレットで利用できるようになります
  • パート8(フラグメント)はサーバーにも送信されず、関連性があり、クライアントにのみ知られています

以下は常に保持されます(URLエンコードの違いを除く)。

requestURI = contextPath + servletPath + pathInfo

サーブレット3.0仕様の次の例は非常に役立ちます。


注:画像が続きます。HTMLで再作成する時間はありません。

ここに画像の説明を入力してください


16

次のサーブレット設定を考えてみます。

   <servlet>
        <servlet-name>NewServlet</servlet-name>
        <servlet-class>NewServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>NewServlet</servlet-name>
        <url-pattern>/NewServlet/*</url-pattern>
    </servlet-mapping>

ここで、URLを押すと、上記のパターンでマッピングされているhttp://localhost:8084/JSPTemp1/NewServlet/jhiため、URL が呼び出さNewServletれます。

ここに:

getRequestURI() =  /JSPTemp1/NewServlet/jhi
getPathInfo() = /jhi

私たちはそれらを持っています:

  • getPathInfo()


    Webコンテナによってデコードされた文字列を返し、サーブレットパスの後、リクエストURLのクエリ文字列の前に来る追加のパス情報を指定します。URLに追加のパス情報がない場合はnull

  • getRequestURI()


    プロトコル名からクエリ文字列までのURLの一部を含む文字列を返します

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