シンプルで非常に軽量なフロントコントローラーを作っています。正しいハンドラーを選択するには、リクエストパスを別のハンドラー(アクション)に一致させる必要があります。
私のローカルマシンHttpServletRequest.getPathInfo()
でHttpServletRequest.getRequestURI()
同じ結果を返します。しかし、私は彼らが本番環境で何を返すのかわかりません。
では、これらの方法と何を選択すればよいのですか?
シンプルで非常に軽量なフロントコントローラーを作っています。正しいハンドラーを選択するには、リクエストパスを別のハンドラー(アクション)に一致させる必要があります。
私のローカルマシンHttpServletRequest.getPathInfo()
でHttpServletRequest.getRequestURI()
同じ結果を返します。しかし、私は彼らが本番環境で何を返すのかわかりません。
では、これらの方法と何を選択すればよいのですか?
回答:
getPathInfo()
サーブレットへのアクセスに使用されるURIの後に追加のパス情報を提供しますgetRequestURI()
。ここで、as は完全なURIを提供します。
そもそもサーブレットを独自のURIパターンで構成する必要があることを考えると、それらは異なるものだと思っていたでしょう。ルート(/)からサーブレットを提供したことがないと思います。
たとえば、サーブレット 'Foo'がURI '/ foo'にマップされている場合、私はそのURIを考えていました。
/foo/path/to/resource
結果として:
RequestURI = /foo/path/to/resource
そして
PathInfo = /path/to/resource
getRequestURI()
は"/foo/path/to/resource"
、期待どおりの文字列が得られますがgetPathInfo()
、同じHttpServletRequest
オブジェクトに対してが得られますnull
。世界で何が起こっているのですか?編集:それは、ユーザー「30thh」によって以下で答えられます。
ここに小さな比較表を置きます(どこかに置くためです):
サーブレットはとしてマップされ/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)、通常は期待どおりに動作しません。
If the url-pattern in the servlet mapping does not end with * (for example /test or *.jsp), getPathInfo() returns null.
鮮やかさ。
getRequestURI()
おりgetRequestURL()
、この場合はデコードされていないjsessionidを返す必要がありS%3F+ID
ます。少なくとも、Tomcat / 8.5.6では実行されます。
クライアントがアドレスバーに入力してサーブレットにアクセスするための完全なURLを分解してみましょう。
http://www.example.com:80/awesome-application/path/to/servlet/path/info?a=1&b=2#boo
パーツは次のとおりです。
http
www.example.com
80
awesome-application
path/to/servlet
path/info
a=1&b=2
boo
リクエストURI(getRequestURIによって返される)は、パート4、5、および6に対応します。
(偶然にも、これを要求していなくても、メソッドgetRequestURLはパート1、2、3、4、5、6を提供します)。
今:
以下は常に保持されます(URLエンコードの違いを除く)。
requestURI = contextPath + servletPath + pathInfo
サーブレット3.0仕様の次の例は非常に役立ちます。
注:画像が続きます。HTMLで再作成する時間はありません。
次のサーブレット設定を考えてみます。
<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の一部を含む文字列を返します