サーブレットのservice()(doPost()・getGet())の引数であるHttpServletRequestのメモ。
|
HTTPリクエストには、POSTメソッドで送られてきた値が入っている。[2007-07-08]
コンソールにデータを出力する例:
@Override protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { req.setCharacterEncoding("MS932"); for (Enumeration i = req.getParameterNames(); i.hasMoreElements();) { String key = (String) i.nextElement(); String val = req.getParameter(key); System.out.printf("%s = %s%n", key, val); } }
HttpServletRequest#setCharacterEncoding()で、リクエストの文字コード体系を指定しておく。(これは、クライアント側で入力に使用した文字コード体系に合わせる)
→ファイルアップロード時の取得方法(multipart/form-data)
→getParameterValues()
パス(URL・URI)取得関連のメソッド。
メソッド | 例(取得されるデータ) | 内容 | 備考 |
---|---|---|---|
getRequestURL() | http://localhost:8080/root/test/zzz/sample.jsp |
クライアントから要求されたURL。 | include等で別のサーブレットが呼ばれた場合でも変わらない。 |
getRequestURI() | /root/test/zzz/sample.jsp |
クライアントから要求されたURI。 | |
getContextPath() | /root |
クライアントから要求されたURIのコンテキストルート。 | |
getServletPath() | /test |
RequestURIの内、url-patternに一致した部分。 | <url-pattern>/test/*</url-pattern> 「*.jsp」等の後方一致だった場合は、RequestURI全て。 |
getPathInfo() | /zzz/sample.jsp |
RequestURIの内、ServletPathを除いた残りの部分。 無い場合はnull。 |
|
getQueryString() | a=1&b=2 |
クライアントから要求されたURLの末尾につけられていた値。 | http://〜sample.jsp?a=1&b=2 他のgetRequestURL()等にはこの情報は付加されていない。 |
getAttribute("javax.servlet.include.request_uri") | null |
別サーブレットがincludeの際に指定したURI。 | 1つのリクエストの中で初めて呼ばれた場合はnull。 そうでない場合は、呼び出し元のサーブレットが指定したURIに対する値。 |
getAttribute("javax.servlet.include.servlet_path") | null |
別サーブレットがincludeの際に指定したURI(のServletPath)。 | |
getAttribute("javax.servlet.include.path_info") | 別サーブレットがincludeの際に指定したURI(のPathInfo)。 無い場合はnull。 |
||
getAttribute("〜") javax.servlet.include.request_uri javax.servlet.include.context_path javax.servlet.include.servlet_path javax.servlet.include.path_info javax.servlet.include.query_string javax.servlet.forward.request_uri javax.servlet.forward.context_path javax.servlet.forward.servlet_path javax.servlet.forward.path_info javax.servlet.forward.query_string |
サーブレット(JSP)では、フォワードやインクルードによって他のサーブレットを呼び出す(処理を委譲する)ことが出来る。
その為、大元のクライアントから渡されるURIと、直前のサーブレットによって指定されたURIを別々に取得できるようになっている。
なお、ここで言うインクルードは、サーブレット内から実行されるRequestDispatcher#include()メソッド。
JSPで言えば、標準アクションタグのインクルードタグ「<jsp:include
page="〜.jsp" />
」のこと。
(JSPのincludeディレクティブ「<%@include
file="〜.jsp" %>
」は、別jspファイルの内容を事前コンパイル時に取り込んで自分の一部にしてしまう為、実行時には呼び出されない)
getParameterValues(name)は、指定されたパラメーターの値を取得するメソッド。[2008-10-19]
HTML(HTTPのGET/POSTメソッド)の場合、同じ名前のパラメーターを指定することが出来るので、getParameterValues()では、同名のパラメーターの全ての値がString配列として返される。
(ちなみに、getParameter()は、String配列の先頭1個目を返す。が、getParameter()は値が1つしか無い(はず)と分かっている場合に使用する)
<form method="POST"> <input name="nm" type="text" value="foo"> <input name="nm" type="text" value="hoge"> <input name="nm" type="text" value="zzz"> </form>
↓
req.getParameterValues("nm")でString[]{ "foo", "hoge", "zzz" }が返る。
ここで、getParameterValues()が返すString配列内の値の順番は保証されるか?という話題がある。(GoogleでもgetParameterValuesで検索すると、「getParameterValues
順番」が検索候補に出てくる)
getParameterValues()のJavadocには順序に関して特に記述が無い。記述が無いということは、厳密に言えば「保証が無い」ということになるとも言える。
また、HTTPのRFCには、順番に関する規定は特に無いらしい。(参考: @IT会議室のgetParameterValuesについて)
しかし、HTML4.01仕様には、<form enctype="application/x-www-form-urlencoded">の場合(つまりデフォルト)は、名前/値はドキュメント(HTML文書)に現れている順序通りとある。
つまり、サーブレットに到達するまで(すなわちブラウザーがセットしたもの)は、HTML内の順番通りに並んでいる(はず)。少なくともHTML4では。
→HTMLのバージョン指定方法(DOCTYPE)
そしてサーブレット仕様2.2には、クエリー文字列(GETメソッドによる名前/値)とPOST本体を合わせて同名パラメーターがある場合に“順序がこうなるはず”という例が載っている。
あくまで例なので、厳密に仕様かと問われるとちょっと怪しい気はしないでもないが…。
ちなみにJBoss4.2.3が準拠しているサーブレットのバージョンは2.4(J2EE1.4)だと思うが、サーブレット仕様2.2も2.5も同じ例が載っているので、2.4も同じだろう
。
そいでもって、JBoss(中身はTomcat)の実装も、POSTメソッド(クエリー文字列)の解釈部分は、同名パラメーターが後から来た場合にString配列の末尾に追加するようコーディングされている。
つまり、パラメーターの現れた順番に値が保持される。
結論としては、getParameterValues()の返す値は、HTML内の順番通りに並んでいると思っていいだろう。少なくともJBoss・Tomcatは。
HTTPのリクエストヘッダーを取得するにはgetHeader()を使用する。
String referer = req.getHeader("referer");
for (Enumeration<?> e = req.getHeaderNames(); e.hasMoreElements();) { String key = (String) e.nextElement(); String val = req.getHeader(key); String msg = String.format("%s= %s", key, val); System.out.println(msg); }
ひとつの名前に複数の値が入る可能性がある場合はgetHeaders()(Enumerationを返す)
数値として取得する場合はgetIntHeader()(intを返す)
日付として取得したい場合はgetDateHeader()(longを返す)
を使う。