こんにちは、みんな!この記事では、サーブレットの基本的な Web 開発概念を理解し、サーブレットを使用して簡単なアプリケーションを作成できるようになります。 不必要な手順を避けるために、最初から開始するのではなく、 Hibernate に関する前回の記事からアプリケーションの作業を続けます。ただし、サーブレットを使い始めたばかりなので、Auto クラスに関連するすべてをアプリケーションから削除し、User クラスとそのアクションだけを残しました。プロジェクトの構造は次のようになります。 つまり、サーブレットです。Wikipedia には、「サーブレットは、その実装によってサーバーの機能が拡張される Java インターフェイスです。サーブレットは、要求と応答の原則を通じてクライアントと対話します。」と記載されています。そして実際その通りです。ここで初めて「クライアント/サーバー アプリケーション アーキテクチャ」という概念に遭遇します。その本質は非常にシンプルで、1 枚の写真に収まります (ここから引用)。
クライアントは、HTTP リクエストを送信してサーバーに接続します。サーバーは必要なデータを生成し (たとえば、データベースからデータを受け取り)、それをクライアントに返します。最も単純な例: 特定のソーシャル ネットワークで [友達] ボタンをクリックすると、サーバーにリクエストが送信されます。サーバーはデータベース内の友人のリストをチェックし、それをあなた (クライアント) に返します。HTTP リクエストのリストは非常に大きいですが、HTTP リクエストに遭遇したことがない場合は、よりよく理解するために、たとえばここでそれらについて読むことをお勧めします。 私たちのタスクは次のとおりです。 サーブレットを使用して CRUD アプリケーションを作成します。アプリケーションは、HTTP リクエストを処理するサーブレットを使用して、データベースからユーザーを作成、変更、削除できる必要があります。Hibernate に関する記事で取り上げたアプリケーションは、これを行う方法をすでに知っていましたが、Java コード、より正確には main() メソッドから直接制御されていました。ここで、リクエストはクライアント、つまりあなたによって送信されます:) 最初に行う必要があるのは、pom.xml ファイルに新しい依存関係を追加することです。
<xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.itis4</groupId>
<artifactId>UsersDaoProject</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
</plugin>
</plugins>
</build>
<dependencies>
<!-- PostgreSQL -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.4.1212.jre7</version>
</dependency>
<!-- Hibernate 5.2.6 Final -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.6.Final</version>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.4.RELEASE</version>
</dependency>
</dependencies>
</project>
3 つの依存関係を追加しました。
- javax.servlet-api ライブラリ自体。
- JSTLタグライブラリ。これはクライアント側、つまり JSP ページを作成するために必要になります。
- Spring-WebMVC。春のクラスが 1 つ必要になりますが、それについては後ほど説明します。
- コンテナ内にサーブレットがない場合。
- サーブレット クラスはコンテナによってロードされます。
- コンテナはサーブレット クラスのインスタンスを作成します。
- コンテナは init() メソッドを呼び出します。このメソッドはサーブレットを初期化し、サーブレットがリクエストを処理できる前に最初に呼び出されます。init() メソッドは、ライフサイクル全体で 1 回だけ呼び出されます。
- クライアントのリクエストに応えます。各リクエストは独自の個別のスレッドで処理されます。コンテナはリクエストごとに service() メソッドを呼び出します。このメソッドは、受信リクエストのタイプを判別し、リクエストを処理するためにこのタイプに対応するメソッドにリクエストを分配します。サーブレット開発者は、これらのメソッドの実装を提供する必要があります。メソッドが実装されていないリクエストを受信した場合、親クラスのメソッドが呼び出され、通常はリクエスト元にエラーが返されて終了します。
- コンテナがサーブレットを削除する必要がある場合、コンテナは destroy() メソッドを呼び出し、サービスからサーブレットを削除します。init() メソッドと同様に、このメソッドもサーブレット サイクル全体で 1 回呼び出されます。
package servlets;
import models.User;
import services.UserService;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
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 UserSimpleServlet extends HttpServlet {
private UserService service = new UserService();
public void init(ServletConfig servletConfig) {
try {
super.init(servletConfig);
} catch (ServletException e) {
e.printStackTrace();
}
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
List<User> users = service.findAllUsers();
req.setAttribute("users", users);
RequestDispatcher dispatcher = req.getRequestDispatcher("/showUsers.jsp");
dispatcher.forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String name = req.getParameter("name");
int age = Integer.parseInt(req.getParameter("age"));
User user = new User(name, age);
service.saveUser(user);
resp.sendRedirect("/users");
}
@Override
protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
int id = Integer.parseInt(req.getParameter("id"));
User user = service.findUser(id);
user.setName(req.getParameter("name"));
user.setAge(Integer.parseInt(req.getParameter("age")));
service.updateUser(user);
resp.sendRedirect("/users");
}
@Override
protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws IOException {
int id = Integer.parseInt(req.getParameter("id"));
service.deleteUser(service.findUser(id));
resp.sendRedirect("/users");
}
}
ご覧のとおり、これには上で説明した init() メソッドが含まれており、4 つの HTTP リクエスト (doGet()、doPost()、doPut()、および doDelete()) に一致する 4 つのメソッドを実装しています。それぞれの機能により、それぞれユーザーの受信、作成、編集、削除が可能になります。これらのメソッドは、javax.servlet.http.HttpServletRequest クラスと javax.servlet.http.HttpServletResponse クラスの入力オブジェクト、つまりサーバーに送信されるリクエストとクライアントが受信するレスポンスを受け取ります。メソッド内では、UserService クラスの必要なメソッドが実行され、クライアントに対する応答が生成されて、/users アドレスにリダイレクトされます。たとえば、 doGet() メソッドでは、すべてのユーザーのリストを取得します。次に、RequestDispatcher クラスのオブジェクトを作成します。これにより、HTTP リクエストにオブジェクトを含めたり、特定のリソース (クライアント JSP ページなど) にリダイレクトしたりできるようになります。doPut() メソッド (ユーザー データの更新) では、HTTP リクエストを処理し、そこから ID、名前、年齢のパラメーターを抽出し、指定された ID を持つユーザーを検索し、そのユーザーに、最初に付けられた名前と年齢を割り当てます。リクエストして、/users ページに戻ります。ただし、これらすべてのメソッドが正しく機能するには、サーブレットを構成する必要があります。このために、WEB-INF フォルダー内の web.xml ファイルを使用します。
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>UserSimpleServlet</servlet-name>
<servlet-class>servlets.UserSimpleServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UserSimpleServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>hiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hiddenHttpMethodFilter</filter-name>
<servlet-name>UserSimpleServlet</servlet-name>
</filter-mapping>
</web-app>
このファイル内のすべてのタグは原則として直感的に理解できますが、順番に見ていきましょう。<welcome-file-list> - 開始 JSP ページが指定されます。アプリケーションの起動時に最初に開かれます。この例では、これはindex.jspページです。<servlet> - UserSimpleServlet クラスをサーブレットとして登録します。<servlet-mapping> は非常に重要なタグです。サーブレットによって処理される URL を定義します。今回の場合、これらはすべて URL なので、単に「/」と示します。しかし、たとえば、ユーザーとそのマシンを含むアプリケーションがある場合、2 番目のサーブレットである SimpleAutoServlet を作成できます。この場合、ユーザー サーブレットのマッピングは「/users」(つまり、ユーザーの処理に関連するリクエスト) となり、自動サーブレットのマッピングは「/autos」になります。そして最後に<フィルター>です。これは、クラス org.springframework.web.filter.HiddenHttpMethodFilter のオブジェクトを内部的に定義します。この記事は Spring に関するものではないので、詳しくは説明しません。これは追加機能としてのみアプリケーションに追加されているということだけは言っておきます。重要なのは、JSP ページを使用してクライアント側を作成するということです。データは、ユーザーのリストを含む表としてページに表示されます。JSP ページ内では、HTML の <form/> タグが使用されます。<form/> からデータを送信するために使用できるのは、HTTP GET リクエストと POST リクエストのみです。つまり、ユーザーの更新、削除、作成という 3 つの操作すべてで、POST リクエストのみを使用する必要があります。PUT リクエストと DELETE リクエストを使用することはできません。原則として、これはごく普通のことであり、実装は簡単ですが、HiddenHttpMethodFilter クラスを使用すると、これらを使用できるようになります。これにより、アプリケーション内の操作の違いが読者にとってより明確になります。最後に、クライアント側に移りましょう。これは 5 つの JSP ページで表されます。インデックス.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Здравствуйте!</title>
</head>
<body>
Если вы хотите начать работу с базой данных пользователей - <br>
нажмите кнопку ниже:
<form action = "users" method="get">
<input type="submit" value="Начать работу с базой данных">
</form>
</body>
</html>
addUser.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Добавить нового пользователя</title>
</head>
<body>
<form action = "/users" method="post">
<input required type="text" name="name" placeholder="Name">
<input required type="text" name="age" placeholder="Возраст">
<input type="submit" value="Сохранить">
</form>
</body>
</html>
deleteUser.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Удалить пользователя</title>
</head>
<body>
Вы действительно хотите удалить пользователя ${param.id}?
&lform action="/users/${param.id}" method="post">
<input type="hidden" name="id" value="${param.id}">
<input type="hidden" name="_method" value="delete">
<input type="submit" value="Удалить">
</form>
</body>
</html>
showUsers.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Список пользователей</title>
</head>
<body>
<table border="2">
<tr>
<td>ID</td>
<td>Name</td>
<td>Возраст</td>
<td>Действия</td>
</tr>
<c:forEach items="${users}" var = "user">
<tr>
<td>${user.getId()}</td>
<td>${user.getName()}</td>
<td>${user.getAge()}</td>
<td>
<form action = "updateUser.jsp" method="post">
<input type="hidden" name="id" value="${user.getId()}">
<input type="hidden" name="name" value="${user.getName()}">
<input type="hidden" name="age" value="${user.getAge()}">
<input type="submit" value="Изменить" style="float:left">
</form>
<form action="deleteUser.jsp" method="post">
<input type="hidden" name="id" value="${user.getId()}">
<input type="submit" value="Удалить" style="float:left">
</form></td>
</tr>
</c:forEach>
</table>
<form action = "addUser.jsp">
<input type="submit" value="Добавить нового пользователя">
</form>
</body>
</html>
updateUser.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Изменить данные пользователя</title>
</head>
<body>
Редактировать пользователя
<form action="/users/${param.id}" method="post">
<input type="hidden" name = "id" value="${param.id}">
<input type="text" name="name" value="${param.name}" placeholder=${param.name}>
<input type="text" name="age" value="${param.age}" placeholder=${param.age}>
<input type="hidden" name="_method" value="put">
<input type="submit" value="Обновить">
</form>
</body>
</html>
JSP ページ (Java サーバー ページ) には、テキスト形式 (HTML、SVG、WML、または XML) のいずれかである静的ソース データと、動的コンテンツを構成する JSP 要素という 2 種類のテキストが含まれています。JSP とは何かを理解するために、ある著者による非常に優れた記事の一部をコピーして貼り付けてみます (ここから)。「基本的に、JSP は最初にアクセスされたときにサーブレットに変換され、サーブレットとして機能します。これを理解することは非常に重要です。JSP はHTML ページのようなページではありません。初心者プログラマにとって、これを明確に理解することが重要です」は別のサーブレットです。出力をプログラムする必要はありません。単に描画するだけで済みます。そして、適切な場所にデータを置き換えることができます。しかし、JSP ページは少なくとも何らかの形で HTML に似ているため、設計者にとっては明らかに簡単です。そして、初心者にもう一度強く言いますが、JSP はサーブレットです。JSP はサーバー上のすべてのデータを使用して準備されます。ここにすべてのデータが挿入されます。そして、ユーザーはブラウザーで既製の HTML ページを受け取ります。 JAVAの兆候があります。」各ページには実行する必要のあるメソッドが含まれているため、JSP ページが実際にサーブレットであることがわかります。たとえば、スタート ページのindex.jsp には、[データベースの操作を開始する] ボタンをクリックすると、method="get" が実行されることが記載されています。新しいユーザーの作成を担当する addUser.jsp ページで、保存ボタンをクリックすると、method="post" が実行されます。JSP の残りの部分は通常の静的 HTML マークアップで構成されているため、詳細については説明しません。これは別の記事のトピックであり、インターネット上に多数の記事が存在します。これでアプリケーションが作成できました。あとは実際に動作をテストするだけです。これを行うには、前述の Apache Tomcat サーブレット コンテナが必要です。Cat は公式 Web サイトからダウンロードできます(私はバージョン 8 を使用しています)。次に、Tomcat 経由でアプリケーションを実行するための構成を IDEA で作成する必要があります。これを行うには、[構成の編集] タブを開き、 新しい構成を作成し 、Tomcat サーバー ローカルを選択します。[アプリケーション サーバー] タブで、Tomcat が配置されているフォルダーへのパスを指定し、 次に [展開] タブに移動します。 ここでは、ローカル サーバー上でのアプリケーションのデプロイメントを構成します。「+」をクリックし、「アーティファクト」を選択します -> プロジェクト名: war (アプリケーションを war ファイルにアセンブルします)。 基本的にはそれだけです!「サーバー」ページでは、同じアプリケーションが「http://localhost:8080/」で実行されることがわかります。この設定を保存し、何か名前を付けます (私の設定名は「Tommy」です)。次に、IDEA の Maven タブ (右側) で、war プラグインを使用してプロジェクトを war ファイルにビルドします (プラグイン -> war -> war:war)。 成功!スタートページが立ち上がりました。次に、「データベースの操作を開始する」ボタンをクリックします。JSP ページindex.jsp は、サーバーによって処理される GET リクエストを生成します。サーバーは応答を生成し、既存のすべてのユーザーのリストの形式で返します (もちろん、ユーザーがデータベース内に存在する場合)。そしてここにあります! ユーザーの 1 人を削除してみましょう。 これも機能します。そこで、サーブレットを使用して最初のアプリケーションを作成しました。ご覧のとおり、すべてはそれほど難しくないことがわかりました:) 宿題として、たとえば、前の記事の車を操作する機能をアプリケーションに戻すことができます。それらの。車用に別のサーブレットと JSP ページを作成し、ユーザーの車のリストを表示し、新しい車を追加し、編集および削除するようにアプリケーションに教えます。PS サーブレットと JSP は非常に古いテクノロジーであり、インターネット上では「こんなジャンクを誰が必要とするのか?」という精神のコメントをよく見かけます。答えは非常に簡単です。これは主に実際のプロジェクトに取り組む人々によって必要とされており、実際のプロジェクトでは、それらを使用して大量のコードが記述される可能性が非常に高いです。そして、それがどのように機能するかを理解せずに、「古いもの」を切り取って新しいものに変えるのは、それでも楽しいです :) JSP とサーブレットのトピックをより徹底的に研究するには、「Head First Servlets and JSP」という書籍を使用できます(英語だけ)。これは有名なスーパーブック「Head First Java」と同じ著者によって書かれたもので、多くの人にとって品質の保証となります :) この記事が読者にとって役に立てば幸いです。新しい記事をご覧になりたい場合は、「いいね」を押してコンテストの著者をサポートすることを忘れないでください。あるいは、さらに良いのは、「とても気に入っています」です :) ご清聴ありがとうございました。勉強頑張ってください!
GO TO FULL VERSION