サーブレットと JSP を使用した単純な Web アプリケーションの作成 (パート 1) 記事を理解するために必要な知識:あなたはすでに Java Core をほぼ理解しており、JavaEE テクノロジと Web プログラミングについて学びたいと考えています。現在、この記事に近いトピックを扱う Java Collections クエストを学習していることが最も合理的です。
最後に、このプロジェクトで練習したい場合は、次のことを試してみてください。
エンティティの作成
エンティティパッケージで、2 つのプライベート文字列変数nameとpasswordUser
を持つクラスを作成します。コンストラクター (デフォルトおよび両方の値を取るコンストラクター) とゲッター/セッターを作成し、念のためメソッドを およびメソッドとともにオーバーライドします。言い換えれば、クラスを作成するときに立派な Java 開発者が行うことはすべて行います。 toString()
equals()
hashCode()
public class User {
private String name;
private String password;
public User() {
}
public User(String name, String password) {
this.name = name;
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", password='" + password + '\'' +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
if (name != null ? !name.equals(user.name) : user.name != null) return false;
return password != null ? password.equals(user.password) : user.password == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + (password != null ? password.hashCode() : 0);
return result;
}
}
これで、ユーザーのリストの作成を開始できます。ユーザーを追加し、そこからユーザーを取得して表示します。ただし、問題が 1 つあります。サーブレット オブジェクトは作成しません。Tomcat がこれをやってくれます。それらでオーバーライドするメソッドはすでに定義されており、パラメーターを使用することはできません。では、両方のサーブレットに表示される共有リストを作成するにはどうすればよいでしょうか? 各サーブレットにリスト オブジェクトを作成するだけの場合、あるリストにユーザーを追加しますが、ListServlet には別のリストのユーザーが表示されます。。したがって、両方のサーブレットによって共有されるオブジェクトが必要です。一般に、プログラム内のすべてのクラスで共有されるオブジェクト、つまりプログラム全体で 1 つのオブジェクトが必要です。デザインパターンについて聞いたことがあると思います。人によっては、プログラムでシングルトンパターンが実際に必要になるのはこれが初めてかもしれません。二重チェックと同期を使って、ちょっと変わったシングルトンを作成することもできます(そう、Tomcat サーブレットは別のスレッドで実行されるため、アプリケーションはマルチスレッド化されています)。ただし、ここでの目的には完全に適切であるため、早期初期化手法を使用することにします。
モデルの作成
モデルパッケージ内にクラスを作成し (そしてSingletonパターンを実装し) 、それを何か珍しい名前にします。たとえば、モデル。クラス内にユーザーのプライベート リストを作成し、2 つのメソッドを実装します。1 つはユーザーを追加するメソッド、もう 1 つは文字列 (ユーザー名) のリストを返すメソッドです。ユーザー オブジェクトはユーザー名とパスワードで構成されており、ユーザーのパスワードを公開したくないため、名前のリストのみを用意します。public class Model {
private static Model instance = new Model();
private List<User> model;
public static Model getInstance() {
return instance;
}
private Model() {
model = new ArrayList<>();
}
public void add(User user) {
model.add(user);
}
public List<String> list() {
return model.stream()
.map(User::getName)
.collect(Collectors.toList());
}
}
MVC について少し
singletonについてはすでに聞いたことがあるので、別の設計パターンであるモデル ビュー コントローラー(MVC)についても聞いたことがあるでしょう。その目的は、ビジネス ロジックをビューから分離することです。つまり、何を行うかを決定するコードと、表示方法を決定するコードを分離することです。ビューはデータの表示方法を担当します。この場合、ビューはJSP ページです。まさにそれが、これらをviewsという名前のフォルダーに配置した理由です。 モデルは、プログラムが実際に動作するデータです。この場合、これはユーザー (ユーザーのリスト) です。そしてコントローラーはそれらの間のリンクです。モデルからデータを取得してビューに渡します (またはTomcatからデータを取得します)、それを処理してモデルに渡します)。ビジネス ロジック (プログラムが行うべきこと) は、モデルやビューではなく、それらの中で定義します。したがって、各部分は独自の業務を処理します。- モデルはデータを保存します。
- ビューはデータを美しく表現します。
- コントローラーはデータ処理を処理します。
<form method="post">
<label>Name:
<input type="text" name="name"><br />
</label>
<label>Password:
<input type="password" name="pass"><br />
</label>
<button type="submit">Submit</button>
</form>
ここで、フォームには値postを持つメソッド属性があります。これは、このフォームからのデータがPOST リクエストとしてサーバーに送信されることを示します。action属性は指定されていません。これは、このページにアクセスしたときと同じアドレス ( /add )にリクエストが送信されることを意味します。したがって、GET リクエストを受信すると、このアドレスにバインドされたサーブレットはユーザー追加フォームを含むJSPを返します。そして、POST リクエストを受信した場合、フォームがここにデータを送信したことがわかります (データは、doPost()
メソッド、プロセス、保存のためにモデルに渡します)。入力フィールドにはname (ユーザー名の場合、またはpassの場合)というパラメーターがあることに注意してください。これは非常に重要な点です。したがって、このデータ (入力されるユーザー名とパスワード) をリクエスト (サーブレット内) から受け取るには、これらの名前フィールドとパスフィールドを使用します。しかし、それについては後で詳しく説明します。データを送信するためのボタンは、通常のように出力フィールドとしてではなく、再びbuttonとして作成されました。このアプローチがどの程度広く採用されているかはわかりませんが、私 (Chrome ブラウザー) では機能します。
POSTリクエストのサーブレット処理
AddServletに戻りましょう。サーブレットがGET リクエストを「キャッチ」できるようにするために、HttpServletdoGet()
クラスのメソッドをオーバーライドしたことを思い出してください。POST リクエストもキャッチするようにサーブレットに教えるには、メソッドをオーバーライドする必要もあります。Tomcat は、これから扱う同様の要求オブジェクトと応答オブジェクトを渡します。まず、リクエストの名前を抽出し、フォームから送信されたパラメーターを渡します (フォームで別の名前を指定した場合は、それらの名前を使用します)。その後、受け取ったデータを使用してユーザーオブジェクトを作成します。次に、モデル オブジェクトを取得し、作成したユーザーをモデルに追加します。 doPost()
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name = req.getParameter("name");
String password = req.getParameter("pass");
User user = new User(name, password);
Model model = Model.getInstance();
model.add(user);
}
データをビューに渡す
ListServletに移りましょう。このdoGet()
メソッドはすでに実装されています。単にコントロールをビュー ( list.jsp ) に移すだけです。これをまだ持っていない場合は、AddServletのメソッドと同様に作成します。ここで、モデルからユーザー名のリストを取得してビューに渡すと、それが受け取られて美しく表示されます。これを行うには、 Tomcatから受け取ったリクエスト オブジェクトを再度使用します。このオブジェクトに属性を追加して、何らかの名前を付けることができます。実際、ビューに渡したいオブジェクトを追加できます。。サーブレットからビューに制御を移すときに、サーブレットが受け取ったのと同じリクエストおよびレスポンス オブジェクトをビューに渡すため、名前のリストをリクエスト オブジェクトに追加し、リクエストからユーザー名のリストを取得できます。ビュー内のオブジェクト。ListServletクラスの作成は完了したので、クラス全体のコードをここに示します。
package app.servlets;
import app.model.Model;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
public class ListServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Model model = Model.getInstance();
List<String> names = model.list();
req.setAttribute("userNames", names);
RequestDispatcher requestDispatcher = req.getRequestDispatcher("views/list.jsp");
requestDispatcher.forward(req, resp);
}
}
JSP ファイルで Java コードを実行する
list.jspを見てみましょう。これは、 ListServlet が制御をそれに移すときにのみ実行されます。さらに、サーブレット内のモデルからユーザー名のリストをすでに準備し、それをリクエスト オブジェクトに渡しました。名前のリストがあるので、for
ループを使用してそれを反復処理し、それぞれの名前を表示できます。前に述べたように、JSP ファイルはJava コードを実行できます(これが、JSP ファイルが静的 HTML ページと異なる点です)。コードを実行するには、次の構成要素を適切な場所に配置するだけです。
<!-- html code -->
<%
// Java code
%>
<!-- html code -->
この構造内で、いくつかの変数にアクセスできます。
- request — サーブレットから渡したリクエスト オブジェクト。単にreqと呼ばれます。
- 応答— 応答オブジェクト (サーブレットではrespと呼ばれます)。
- out — JspWriterオブジェクト (通常のWriterを継承)。これを使用して、HTML ページ自体に何かを直接「書き込む」ことができます。ステートメントout.println("Hello, World!") はSystem.out.println("Hello, World!")に非常に似ていますが、混同しないでください。
- out.println() はHTML ページに「書き込み」、System.out.println はシステム出力ストリームに書き込みます。Java コードを含むJSPセクション内でSystem.out.println()を呼び出すと、結果はTomcatコンソールに表示されますが、ページには表示されません。
<ul>
<%
List<String> names = (List<String>) request.getAttribute("userNames");
if (names != null && !names.isEmpty()) {
for (String s : names) {
out.println("<li>" + s + "</li>");
}
}
%>
</ul>
ユーザーがいる場合にのみリストを表示し、それ以外の場合はまだユーザーがいないという警告を表示する必要がある場合は、このセクションを少し書き直すことができます。
<%
List<String> names = (List<String>) request.getAttribute("userNames");
if (names != null && !names.isEmpty()) {
out.println("<ui>");
for (String s : names) {
out.println("<li>" + s + "</li>");
}
out.println("</ui>");
} else out.println("<p>There are no users yet!</p>");
%>
サーブレットからビューにデータを渡す方法がわかったので、ユーザーの追加の成功に関する通知を表示するようにAddServletを改善できます。これを行うには、doPost()
メソッド内で、新しいユーザーをモデルに追加した後、このユーザー名をreqオブジェクトの属性に追加し、制御をビュー( add.jsp )に戻すことができます。次に、Java コードを含むセクションを追加します。そこで、リクエストにそのような属性があるかどうかを確認し、属性がある場合は、ユーザーが正常に追加されたことを示すメッセージを表示します。これらの変更後、AddServletの完全なコードは次のようになります。
package app.servlets;
import app.entities.User;
import app.model.Model;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class AddServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
RequestDispatcher requestDispatcher = req.getRequestDispatcher("views/add.jsp");
requestDispatcher.forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name = req.getParameter("name");
String password = req.getParameter("pass");
User user = new User(name, password);
Model model = Model.getInstance();
model.add(user);
req.setAttribute("userName", name);
doGet(req, resp);
}
}
ここでは、メソッドの最後に、doPost()
モデルに追加されたユーザーの名前を持つ属性を作成し、メソッドを呼び出してdoGet()
、現在のリクエストとレスポンスを渡します。このdoGet()
メソッドは制御をビューに移し、追加されたユーザーの名前が属性として付加されたリクエスト オブジェクトも受け取ります。私たちがやるべきことは、そのような属性がない場合に通知を表示するようにadd.jspを修正することです。add.jspの最終バージョンは次のとおりです。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Add new user</title>
</head>
<body>
<div>
<h1>Super app!</h1>
</div>
<div>
<%
if (request.getAttribute("userName") != null) {
out.println("<p>User '" + request.getAttribute("userName") + "' added!</p>");
}
%>
<div>
<div>
<h2>Add user</h2>
</div>
<form method="post">
<label>Name:
<input type="text" name="name"><br />
</label>
<label>Password:
<input type="password" name="pass"><br />
</label>
<button type="submit">Submit</button>
</form>
</div>
</div>
<div>
<button onclick="location.href='/'">Back to main</button>
</div>
</body>
</html>
ページ本文は次のもので構成されます。
- ヘッダー付きの div。
- コンテンツの div コンテナ。これには、ユーザー名を持つ属性が存在するかどうかのチェックが含まれます。
- ユーザー追加フォームを含む div。
- 下部には、ホームページに戻るボタンのあるフッターがあります。
<%@ page import="java.util.List" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Users</title>
</head>
<body>
<div>
<h1>Super app!</h1>
</div>
<div>
<div>
<div>
<h2>Users</h2>
</div>
<%
List<String> names = (List<String>) request.getAttribute("userNames");
if (names != null && !names.isEmpty()) {
out.println("<ui>");
for (String s : names) {
out.println("<li>" + s + "</li>");
}
out.println("</ui>");
} else out.println("<p>There are no users yet!</p>");
%>
</div>
</div>
<div>
<button onclick="location.href='/'">Back to main</button>
</div>
</body>
</html>
これにより、ユーザーを保存および追加し、ユーザー名のリストを表示できる、完全に動作する Web アプリケーションが完成しました。あとはそれを美しくするだけです… :)
スタイルを追加します。W3.CSS フレームワークを使用します
現時点では、アプリケーションは動作しますが、まったくとんでもないものに見えます。そこで、背景を追加し、テキストとボタンに色を付け、リストにスタイルを追加し、要素を整列させ、インデントを追加してみましょう。手動でスタイルを記述すると、多くの時間がかかり、神経を圧迫する可能性があります。そこで私は、W3.CSSフレームワークの使用を提案します。スタイルを備えたすぐに使用できるクラスがすでに用意されています。必要なのは、使用したい CSS クラスを適切な場所に配置することだけです。これらをページに追加するには、まずスタイル ファイルを接続します。これを行うには 2 つの方法があります。-
ページにアクセスし、次のスタイル ファイルへの直接リンクを head セクションに挿入します。
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
このオプションは、インターネットに常時接続している場合に適しています。ローカル サーバーでページを開くと、スタイルがインターネットから取得されます。
-
ただし、インターネット接続に依存せず、すべてのスタイルをローカルに置きたい場合は、スタイル ファイルをダウンロードし、 Webフォルダー内のどこかに配置します(例: web/styles/w3.css )。次に、すべてのページ ( index.html、add.jsp、list.jsp ) に目を通し、headセクション内のスタイル ファイルに次のリンクを追加します。
<link rel="stylesheet" href="styles/w3.css">
その後、タグを調べて、好きなスタイルを追加するだけです。これについては詳しくは説明しません。代わりに、ラスター スタイルのクラスを備えた 3 つのファイルのすぐに使用できるバージョンを提供することにします。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Super app!</title>
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
</head>
<body class="w3-light-grey">
<div class="w3-container w3-blue-grey w3-opacity w3-right-align">
<h1>Super app!</h1>
</div>
<div class="w3-container w3-center">
<div class="w3-bar w3-padding-large w3-padding-24">
<button class="w3-btn w3-hover-light-blue w3-round-large" onclick="location.href='/list'">List users</button>
<button class="w3-btn w3-hover-green w3-round-large" onclick="location.href='/add'">Add user</button>
</div>
</div>
</body>
</html>
add.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Add new user</title>
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
</head>
<body class="w3-light-grey">
<div class="w3-container w3-blue-grey w3-opacity w3-right-align">
<h1>Super app!</h1>
</div>
<div class="w3-container w3-padding">
<%
if (request.getAttribute("userName") != null) {
out.println("<div class=\"w3-panel w3-green w3-display-container w3-card-4 w3-round\">\n" +
" <span onclick=\"this.parentElement.style.display='none'\"\n" +
" class=\"w3-button w3-margin-right w3-display-right w3-round-large w3-hover-green w3-border w3-border-green w3-hover-border-grey\">×</span>\n" +
" <h5>User '" + request.getAttribute("userName") + "' added!</h5>\n" +
"</div>");
}
%>
<div class="w3-card-4">
<div class="w3-container w3-center w3-green">
<h2>Add user</h2>
</div>
<form method="post" class="w3-selection w3-light-grey w3-padding">
<label>Name:
<input type="text" name="name" class="w3-input w3-animate-input w3-border w3-round-large" style="width: 30%"><br />
</label>
<label>Password:
<input type="password" name="pass" class="w3-input w3-animate-input w3-border w3-round-large" style="width: 30%"><br />
</label>
<button type="submit" class="w3-btn w3-green w3-round-large w3-margin-bottom">Submit</button>
</form>
</div>
</div>
<div class="w3-container w3-grey w3-opacity w3-right-align w3-padding">
<button class="w3-btn w3-round-large" onclick="location.href='/'">Back to main</button>
</div>
</body>
</html>
リスト.jsp
<%@ page import="java.util.List" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Users list</title>
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
</head>
<body class="w3-light-grey">
<div class="w3-container w3-blue-grey w3-opacity w3-right-align">
<h1>Super app!</h1>
</div>
<div class="w3-container w3-center w3-margin-bottom w3-padding">
<div class="w3-card-4">
<div class="w3-container w3-light-blue">
<h2>Users</h2>
</div>
<%
List<String> names = (List<String>) request.getAttribute("userNames");
if (names != null && !names.isEmpty()) {
out.println("<ul class=\"w3-ul\">");
for (String s : names) {
out.println("<li class=\"w3-hover-sand\">" + s + "</li>");
}
out.println("</ul>");
} else out.println("<div class=\"w3-panel w3-red w3-display-container w3-card-4 w3-round\">\n"
+
" <span onclick=\"this.parentElement.style.display='none'\"\n" +
" class=\"w3-button w3-margin-right w3-display-right w3-round-large w3-hover-red w3-border w3-border-red w3-hover-border-grey\">×</span>\n" +
" <h5>There are no users yet!</h5>\n" +
"</div>");
%>
</div>
</div>
<div class="w3-container w3-grey w3-opacity w3-right-align w3-padding">
<button class="w3-btn w3-round-large" onclick="location.href='/'">Back to main</button>
</div>
</body>
</html>
以上です。:) まだご質問やコメントがある場合、または何かがうまくいかない場合は、コメントを残してください。そして、それがどのようになったのかを示すスクリーンショットをいくつか添付します。
- ユーザーを削除するためのサーブレットと JSP を作成し、既存のユーザーを編集するための別のペアを追加します。その結果、サーブレットを使用して構築された本物の CRUD Web アプリケーションが作成されます。;)
- サーバーの再起動後に追加されたユーザーが消えないように、リストをデータベースに置き換えます。:)