[解決済み] サーブレットにおけるdoGetとdoPost
質問
サーブレットに情報を送信するHTMLページを開発しました。Servletの中で、メソッド
doGet()
と
doPost()
:
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
String id = req.getParameter("realname");
String password = req.getParameter("mypassword");
}
public void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
String id = req.getParameter("realname");
String password = req.getParameter("mypassword");
}
サーブレットを呼び出すhtmlページのコードでは
<form action="identification" method="post" enctype="multipart/form-data">
User Name: <input type="text" name="realname">
Password: <input type="password" name="mypassword">
<input type="submit" value="Identification">
</form>
を使う場合
method = "get"
を使うと、id と password の値が得られますが、Servlet で
method = "post"
を使うと、id と password は
null
. この場合、なぜ値が取得できないのでしょうか?
もう一つ知りたいのは、Servletによって生成または検証されたデータをどのように使うかということです。例えば、上記のServletがユーザーを認証した場合、HTMLページにユーザーIDを表示したいと思います。文字列 'id' を応答として送信し、この情報を私のHTMLページで使用することができるはずです。それは可能ですか?
どのように解決するのですか?
はじめに
この場合
doGet()
で遮蔽したい場合は
HTTP GET リクエスト
. この場合
doPost()
で遮蔽したい場合は
HTTP POST リクエスト
. 以上です。一方から他方へ、あるいはその逆へ移植しないでください(例えば、Netbeansの不幸な自動生成された
processRequest()
メソッドのような)。これは全く意味をなしません。
GET
通常、HTTP GET リクエストは
べき乗
. つまり、リクエストを実行するたびにまったく同じ結果を得ることができます (認証/オーセンティケーションや、検索結果や最新ニュースなど、ページの時間的な性質は考慮の対象外です)。ブックマーク可能なリクエストについて話すことができます。リンクをクリックする、ブックマークをクリックする、ブラウザのアドレスバーに生のURLを入力する、などなど、すべてHTTP GETリクエストを発生させます。もしサーブレットがその URL をリッスンしていれば、その
doGet()
メソッドが呼び出されます。これは通常
前処理
リクエストの前処理に使われます。つまり、JSP から HTML 出力を表示する前に、テーブルに表示するためのデータを収集するなど、いくつかのビジネス的なことを行うのです。
@WebServlet("/products")
public class ProductsServlet extends HttpServlet {
@EJB
private ProductService productService;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Product> products = productService.list();
request.setAttribute("products", products); // Will be available as ${products} in JSP
request.getRequestDispatcher("/WEB-INF/products.jsp").forward(request, response);
}
}
JSP ファイルは明示的に
/WEB-INF
フォルダに置かれることに注意してください。これは、エンドユーザが前処理サーブレットを呼び出さずに直接アクセスできるようにするためです(したがって、空のテーブルを見て混乱してしまうことになります)。
<table>
<c:forEach items="${products}" var="product">
<tr>
<td>${product.name}</td>
<td><a href="product?id=${product.id}">detail</a></td>
</tr>
</c:forEach>
</table>
また、上記の最後のコラムにあるような詳細の表示/編集リンクは通常べき乗です。
@WebServlet("/product")
public class ProductServlet extends HttpServlet {
@EJB
private ProductService productService;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Product product = productService.find(request.getParameter("id"));
request.setAttribute("product", product); // Will be available as ${product} in JSP
request.getRequestDispatcher("/WEB-INF/product.jsp").forward(request, response);
}
}
<dl>
<dt>ID</dt>
<dd>${product.id}</dd>
<dt>Name</dt>
<dd>${product.name}</dd>
<dt>Description</dt>
<dd>${product.description}</dd>
<dt>Price</dt>
<dd>${product.price}</dd>
<dt>Image</dt>
<dd><img src="productImage?id=${product.id}" /></dd>
</dl>
POST
HTTP POST リクエストはべき乗ではありません。エンドユーザーがリダイレクトを実行していないURLであらかじめPOSTフォームを送信していた場合、そのURLは必ずしもブックマーク可能とは限りません。送信されたフォームのデータは、URLに反映されません。URLを新しいブラウザのウィンドウやタブにコピーしても、フォーム送信後と全く同じ結果になるとは限りません。このようなURLは、ブックマークには登録できません。もし Servlet が当該 URL を待ち受けているならば、その
doPost()
が呼び出されます。これは通常
ポストプロセス
リクエストに使用されます。つまり、送信されたHTMLフォームからデータを収集し、それを使っていくつかのビジネス上のことを行います(変換、検証、DBへの保存、など)。最終的に通常、結果は転送されたJSPページからのHTMLとして表示されます。
<form action="login" method="post">
<input type="text" name="username">
<input type="password" name="password">
<input type="submit" value="login">
<span class="error">${error}</span>
</form>
...このServletの一部と組み合わせて使用することができます。
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
@EJB
private UserService userService;
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
User user = userService.find(username, password);
if (user != null) {
request.getSession().setAttribute("user", user);
response.sendRedirect("home");
}
else {
request.setAttribute("error", "Unknown user, please try again");
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
}
}
ほら、もし
User
が DB で見つかった場合 (すなわち、ユーザ名とパスワードが有効である場合)、その後に
User
はセッションスコープに置かれ (つまり "logged in") サーブレットはメインページにリダイレクトします (この例では
http://example.com/contextname/home
にリダイレクトされます)、さもなければエラーメッセージをセットして 同じ JSP ページにリクエストを戻し、そのメッセージが
${error}
.
必要であれば、quot;hide" で
login.jsp
で
/WEB-INF/login.jsp
で囲むことで、ユーザはサーブレットからしかアクセスできないようにします。これによって URL がきれいに保たれます
http://example.com/contextname/login
. 必要なのは
doGet()
をこのようにサーブレットに追加するだけです。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
}
(の同じ行を更新してください)。
doPost()
というように)
とはいえ、ただ単に遊びで闇雲に撮影しているだけなのかどうかはわかりませんが、投稿されたコードはあまり良い印象を受けません(例えば
compareTo()
の代わりに
equals()
を使用する代わりに、パラメータ名を掘り下げます。
getParameter()
と
id
と
password
はサーブレットインスタンス変数として宣言されているように見えますが、これは
スレッドセーフ
). というわけで、Java SE の基本的な API について
Oracleチュートリアル
(の章をご覧ください)、また、JSP/サーブレットを正しく使うには
これらのチュートリアル
.
こちらもご覧ください。
- サーブレットウィキページ
- Java EE ウェブ開発、何から始めればいいのか、どんなスキルが必要なのか?
- サーブレットは "HTTPステータス404 要求されたリソース(/servlet)は利用できません"を返します。
- MVCとDAOパターンを使用して、JSPページでJDBC結果セットをHTMLで表示する
更新
: あなたの質問の更新に従って (これはかなり重要です。あなたの元の質問の部分を削除してはいけません、これは答えが価値のないものになるでしょう...むしろ)
を加える
を新しいブロックに追加してください) 、それはあなたが不必要にフォームのエンコードタイプを設定することが判明した
multipart/form-data
. これは、リクエストパラメータを (デフォルトの)
application/x-www-form-urlencoded
とは異なり、 リクエストパラメータをクエリ文字列として送ります (例えば
name1=value1&name2=value2&name3=value3
). 必要なのは
multipart/form-data
が必要なだけです。
<input type="file">
要素があると、文字以外のデータ (バイナリデータ) である可能性があるファイルをアップロードするためのフォームが表示されます。あなたの場合はそうではないので、これを削除すれば期待通りに動作するようになります。もしファイルをアップロードする必要があるなら、エンコードタイプを設定し、リクエストボディを自分でパースする必要があります。通常、あなたは
Apache Commons FileUpload
を使いますが、新しいサーブレット 3.0 API を使っている場合は
HttpServletRequest#getPart()
. 具体的な例として、こちらの回答もご覧ください。
JSP /サーブレットを使用してサーバーにファイルをアップロードする方法は?
関連
-
mvn' は、内部または外部のコマンド、操作可能なプログラムまたはバッチファイルとして認識されません。
-
型に解決できない エラー解決
-
Javaジェネリックを1つの記事で
-
Junitのユニットテストエラー
-
Java Runtime Environmentを継続するためのメモリが不足しています。
-
Java:未解決コンパイル問題の解決方法
-
[解決済み] JavaにおけるHashMapとHashtableの違いは何ですか?
-
[解決済み] Javaにおけるpublic、protected、package-private、privateの違いは何ですか?
-
[解決済み] serialVersionUIDとは何ですか、またなぜそれを使用する必要がありますか?
-
[解決済み】サーブレットはどのように動作するのですか?インスタンス化、セッション、共有変数とマルチスレッド
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] doGet()とdoPost()のフロー上の違いは何ですか?[重複している]。
-
アクセス制限です。タイプ 'Application' は API ではない(必要なライブラリに制限がある)。
-
executeQuery()でデータ操作文が発行できない。解決方法
-
Git Pull Failed マージされていないファイルがあるため、Pull できません。
-
ajax コミット リソースの読み込みに失敗しました: サーバーはステータス 400 で応答しました ()
-
BindException: アドレスはすでに使用中です:バインドエラー解決
-
アノテーション「@Retention」の役割
-
Javaがリソースリークに遭遇した:'input'が閉じない 解決方法
-
Java Runtime Environmentを継続するためのメモリが不足しています。
-
swagger2 モデルが表示されない モデルが見つからない @ApiModel アノテーションが表示されない問題