目次
1. サーブレットを要求するブラウザのプロセス分析 (重要):
2. サーブレット (HttpServlet) を開発するための正しいアプローチ:
3. アノテーションメソッドを使用してサーブレットを開発します。
1. サーブレットによるクイックスタート
1. サーブレットが必要な理由は何ですか?
ブラウザがWeb サーバーから静的な Web リソース (HTML、CSS、JS、画像など) をリクエストすると、Tomcat はリクエストを解析してリソースを取得し、関係なしに応答の形式でブラウザに直接返すことができます。データベースと一緒に。現時点では、Tomcat は通常の Web サービスのみを提供します。
ただし、ブラウザがユーザーメッセージ、ユーザー コメント、データベースに直接リンクされているその他の要件など、ユーザーと動的に対話するリクエストを発行する場合、サーブレットはそれを実装するために他の Java プログラムを呼び出す必要があります。Java プログラムは通常階層化されています。 (サービス、DAOなど)。Tomcat は Servlet をサポートしており、Servlet の解析を完了できるため、現時点ではTomcat が Servlet のコンテナ (エンジンとも呼ばれます) として機能します。
2.サーブレットとは何ですか?
サーブレットは動的な WEB プロジェクトの開発で広く使用されており、SpringMVC と SpringBoot の基礎となっています。
サーブレットの本来の意味は Java サーバー アプレットであり、次のような特徴があります。
①サーバーによって呼び出され、実行されます(例: Tomcatによって解析されて実行されます)。② Java言語で書かれており、本質的にはJavaクラスであり、他の Java プログラム (サーブレット エンジン) から呼び出すことができますが、独立して実行することはできません。
③サーブレット仕様に従って開発します(JDBCインターフェース仕様と同様に、TomcatやWebLogicなどの仕様に準拠したWebサーバーがサーブレットをサポートできます)。
④サーブレットは強力で、Web サイトのほぼすべての機能を実行できますが、技術スタックに対する要件が高くなります。
3.サーブレット開発手順:
Web.xml はservlet3.0 より前に使用されていましたが 、servlet3.0 以降のバージョン ( 3.0 を含む) ではアノテーションがサポートされ (実際にはさらに多くのものが使用されています) 、web.xml 構成もサポートされています。 PS: ネイティブサーブレットがプロジェクトで使用されることはほとんどありません。
4. はじめるケース:
まず、新しいプロジェクトを作成し、Web アプリケーションフレームワークのサポートを導入し、WEB-INF ディレクトリに新しい lib ディレクトリを作成します。以下に示すように:
次に、次の図に示すように、Servlet に必要な jar パッケージ「servlet-api.jar」をTomcat lib ディレクトリにインポートします。
インポート後、次の図に示すように、現在のプロジェクトにデプロイする必要があります。
次に、Tomcat を設定します。
次に、新しいクラスを作成し、サーブレット インターフェイスを実装して、サーブレット インターフェイスの 5 つのメソッドをオーバーライドします。
TryServlet クラスのコードは次のとおりです: (コメントに注意してください)。
package intro;
import jakarta.servlet.*;
import java.io.IOException;
/**
* @author : Cyan_RA9
* @version : 21.0
*/
/** 一个类只有实现了Servlet接口,才能被当作Servlet使用。 */
public class TryServlet implements Servlet {
//创建TryServlet实例时会调用init方法,该方法只会被调用一次。
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("init方法被调用");
}
//返回ServletConfig对象,即返回Servlet的配置信息
@Override
public ServletConfig getServletConfig() {
return null;
}
/*
(1)service方法用于处理浏览器的请求(包括get/post)
(2)每当浏览器请求一次Servlet时,都会调用一次service方法。
(3)当Tomcat调用该方法时,会将请求的数据封装成实现了ServletRequest接口的servletRequest对象,
通过servletRequest对象,可以得到用户提交的数据。
(4)servletResponse对象可以用于返回数据给Tomcat,Tomcat解析得到对应的数据后,
会再把数据封装成HTTP响应的方式,发送给浏览器,浏览器再解析并显示。
*/
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("This is the first Servlet try~");
}
//返回servlet信息,使用较少
@Override
public String getServletInfo() {
return null;
}
//该方法是在servlet被销毁时被Tomcat调用,只调用一次
@Override
public void destroy() {
System.out.println("destroy方法被调用。");
}
}
web.xml でTryServlet を構成します。つまり、外部アクセス アドレスをTryServletに提供します。web.xml は主に、Web アプリケーションで使用されるサーブレットを構成するために使用されます。web.xml コードは次のとおりです。
<?xml version="1.0" encoding="UTF-8"?>
<web-app 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_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>TryServlet</servlet-name>
<servlet-class>intro.TryServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>TryServlet</servlet-name>
<url-pattern>/tryServlet</url-pattern>
</servlet-mapping>
</web-app>
<!--
1.<servlet>:
(1)<servlet-name>指给当前Servlet取名(由程序员手动指定,但一般取类名),该名字唯一。
(2)<servlet-class>此处为Servlet类的全路径(全类名);Tomcat在反射生成该Servlet时需要使用。
2.<servlet-mapping>:
(1)<servlet-name>同上
(2)<url-pattern>是该servlet访问URL的配置(路径)
当前访问形式:http://localhost:8080/Servlet_Demo/tryServlet
-->
操作効果 (下の GIF 画像):
2. サーブレットのライフサイクル
1. サーブレットをリクエストするブラウザのプロセス分析 (重要):
1° ブラウザはまず URL からホスト名を解析します(例: www.baidu.com)。
2° ブラウザは、ローカル マシンの C:\Windows\System32\drivers\etc ディレクトリにある host ファイルに移動して、ホスト名に対応する IP があるかどうかを確認します。以下に示すように:
3° ドメイン名に対応する IP が本機の hosts ファイルに見つからない場合は、外部ネットワークの DNS (ドメイン ネーム システム) を参照して検索を続けますが、それでも見つからない場合は、プロンプトが表示されます。次の図に示すように、Web サイトが見つからないことがわかります。
ブラウザが hosts ファイルまたは DNS サーバー内のホスト名に対応する IP を正常に見つけると、取得した IP に基づいてTomcat に HTTP リクエストを発行します。
4° Tomcat は HTTP リクエストを受信した後に判断します。それが最初のリクエストの場合、Tomcat は web.xml 設定ファイルをクエリして、リクエストされたリソース (例: /tryServlet) が <servlet-mapping の URL にあるかどうかを確認します。 >- パターン設定 (つまり、サーブレットが web.xml ファイルで設定されているかどうか)。対応する URL パターンが見つかった場合は、<servlet-name> (例: TryServlet) が取得されますが、見つからなかった場合、Tomcat はブラウザに 404 ページ (リソースが見つかりません) を返します。
Tomcat は、少なくとも 2 つの素晴らしい大きな HashMap コンテナを維持します。そのうちの 1 つは HashMap<id, Servlet> で、ID は <servlet-name> ( non-repeatable ) として保存され、Servlet は Servlet インスタンスを保存します。Tomcat は、ID によって HashMap をクエリして、サーブレット インスタンス (リフレクションによって作成された) が存在するかどうかを確認します。
別の HashMap コンテナでは、キーは web.xml 構成ファイルの <servlet-mapping> に <url-pattern> を格納するために使用され、値は <servlet-name> を格納するために使用されます。(したがって、対応する <servlet-name> を取得する前に、まず URL パターンを取得する必要があります。 )<servlet-name> に対応する ID が見つからない
場合Tomcat は、 <servlet-name> に基づいて <servlet-class> 内の完全なクラス名を取得し、リフレクション技術を使用してサーブレットをインスタンス化し(init メソッドを呼び出し)、そのサーブレット インスタンスを維持されている HashMap コレクションに追加します。
5° 次に、Tomcat はサービス メソッドを呼び出し、対応するサーブレット インスタンスがサービスを処理します。アクセス要求ごとに、サーブレットエンジンは新しいHttpServletRequest要求オブジェクトと新しいHttpServletResponse応答オブジェクトを作成し、これら 2 つのオブジェクトをパラメータとして使用します。呼び出すサーブレットのservice()メソッドに渡すと、serviceメソッドはリクエスト メソッドに従って doGet | dePost | その他のメソッドを呼び出します。
6°サーブレット インスタンスが HashMap コレクションで見つかった場合、サーブレットのサービス メソッドが直接呼び出されます。サーブレットがメモリ内に常駐し、シングルトン (インスタンスが 1 つだけ) であることがわかります。
7°サーブレット インスタンスがサービス メソッドの処理を完了すると、データは HttpServletResponse オブジェクトの形式で Tomcat に返されます。
8° Tomcat は HttpServletResponse オブジェクトを解析してデータを取得し、そのデータを HTTP 応答にパッケージ化して、HTTP 応答の形式でブラウザに返します。
9°ブラウザは返された結果を解析して表示します。
追伸:
静的 Web リソース (html、css、js、画像など) に対するブラウザのリクエストは、実際にはTomcatのDefaultServletによって完了されます。他のutl パターンが一致しない場合、 Tomcat はDefaultServlet. リソースを通じて他の静的ファイルをインターセプトします。
2. ライフサイクル:
1° 初期化フェーズ
Tomcat などのサーブレット コンテナの場合、サーブレットをロードした後、サーブレット コンテナはサーブレット インスタンスを作成し、init() メソッドを呼び出します。init() メソッドは 1 回だけ呼び出されます (サーブレットはシングルトンであるため、クラスはロードされるのは 1 回だけです)。各リクエストにより、サーブレットエンジンはサーブレットのサービスメソッドを呼び出します。
サーブレット コンテナは、次の条件でサーブレットをロードします。
(1)サーブレット コンテナ (Tomcat) の起動時に特定のサーブレットを自動的にロードするには、<load-on-startup>1</load-on-startup> を web.xml ファイルに追加する必要があります。ここで、1 は順序を表します。サーブレットがロードされるもの。
(2)サーブレット コンテナが開始された後、ブラウザは初めてサーブレット リクエストを送信します。
(3)サーブレットがリロードされた後 (例: Tomcat が再デプロイ操作を実行するとき[再デプロイ操作により、現在の HashMap 内のすべてのサーブレット インスタンスが破棄されます) Tomcat によって維持されるコレクション] )、ブラウザが初めてサーブレットにリクエストを再度送信するときにも、サーブレットがロードされます。
2° 処理要求ステージ
1. リクエスト処理段階は、サーブレットによるサービス メソッドの呼び出しです。2. HTTP リクエストを受信するたびに、サーバーは HTTP リクエストを処理するための新しいスレッドを生成します。3. HTTP 要求メッセージを カプセル化する ServletRequestオブジェクト と、 HTTP 応答メッセージを表す ServletResponse オブジェクトを作成します。4. 次に、 Servlet の service() メソッドを呼び出し、リクエスト オブジェクトとレスポンス オブジェクトをパラメータとして渡します。
3° 終了フェーズ
Web アプリケーションが終了するか、 サーブレット コンテナが終了するか、 サーブレット クラスがリロードされると、 Tomcat の再起動やWeb アプリケーションの再デプロイなど、 destroy() メソッドが呼び出されます 。
3. サーブレットの基本的な使い方
1. Get リクエストと Post リクエストの処理:
単純なフォームの送信を例として、register.html コードは次のとおりです。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Register</title>
</head>
<body>
<h1>User Register</h1>
<form action="http://localhost:8080/Servlet_Demo/tryServlet" method="post">
username:<input type="text" name="username"/> <br/><br/>
<input type="submit" value="register"/>
</form>
</body>
</html>
TryServlet クラスで doGet メソッドと doPost メソッドを定義して、GET リクエストと POST リクエストをそれぞれ処理します。改善されたTryServlet クラス コードは次のとおりです。
package intro;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* @author : Cyan_RA9
* @version : 21.0
*/
/** 一个类只有实现了Servlet接口,才能被当作Servlet使用。 */
public class TryServlet implements Servlet {
//创建TryServlet实例时会调用init方法,该方法只会被调用一次。
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("init方法被调用");
}
//返回ServletConfig对象,即返回Servlet的配置信息
@Override
public ServletConfig getServletConfig() {
return null;
}
/*
(1)service方法用于处理浏览器的请求(包括get/post)
(2)每当浏览器请求一次Servlet时,都会调用一次service方法。
(3)当Tomcat调用该方法时,会将请求的数据封装成实现了ServletRequest接口的request对象,
通过servletRequest对象,可以得到用户提交的数据。
(4)servletResponse对象可以用于返回数据给Tomcat,Tomcat解析得到对应的数据后,
会再把数据封装成HTTP响应的方式,发送给浏览器,浏览器再解析并显示。
*/
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("service is invoked...");
/*
ServletRequest类中没有getMethod方法,
因此要将其转换为它的子接口类型HttpServletRequest.
*/
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
String method = httpServletRequest.getMethod();
System.out.println("method = " + method);
if ("GET".equals(method)) {
doGet();
} else if ("POST".equals(method)) {
doPost();
}
}
//处理GET请求
public void doGet() {
System.out.println("doGet() is invoked");
}
//处理POST请求
public void doPost() {
System.out.println("dePost() is invoked");
}
//返回servlet信息,使用较少
@Override
public String getServletInfo() {
return null;
}
//该方法是在servlet被销毁时被Tomcat调用,只调用一次
@Override
public void destroy() {
System.out.println("destroy方法被调用。");
}
}
実行結果:
2. サーブレット (HttpServlet) を開発するための正しいアプローチ:
HttpServlet クラスのクラス図は次のとおりです。
HttpServlet は GenericServlet クラス (抽象クラス) を直接継承し、GenericServlet クラスは Servlet インターフェイスの 5 つのメソッドすべてを実装します。HttpServlet には doGet メソッドと doPost メソッドも用意されており、メソッドの種類は実装されたサービス メソッドで判断されるため、HttpServlet の最下層は実際には Servlet と同じですが、カプセル化されています。
HttpServlet を使用したサーブレットの開発手順は次のとおりです。
1. HttpServlet クラスを継承するクラスを作成します。2. ビジネス ニーズに応じて doGet メソッドまたは doPost メソッドを書き直す3. web.xml で サーブレット プログラムを構成します。
NBServlet をデモンストレーション クラスとして 使用すると、コードは次のようになります。
package advance;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author : Cyan_RA9
* @version : 21.0
*/
public class NBServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("NBServlet's doGet is invoked~");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("NBServlet's doPost is invoked~");
}
}
web.xml が再構成された後のコードは次のようになります。
<?xml version="1.0" encoding="UTF-8"?>
<web-app 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_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>TryServlet</servlet-name>
<servlet-class>intro.TryServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>TryServlet</servlet-name>
<url-pattern>/tryServlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>NBServlet</servlet-name>
<servlet-class>advance.NBServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>NBServlet</servlet-name>
<url-pattern>/nBServlet</url-pattern>
</servlet-mapping>
</web-app>
<!--
1.<servlet>:
(1)<servlet-name>指给当前Servlet取名(由程序员手动指定,但一般取类名),该名字唯一。
(2)<servlet-class>此处为Servlet类的全路径(全类名);Tomcat在反射生成该Servlet时需要使用。
2.<servlet-mapping>:
(1)<servlet-name>同上
(2)<url-pattern>是该servlet访问URL的配置(路径)———一般采取类名首字母小写的形式.
当前访问形式:http://localhost:8080/Servlet_Demo/tryServlet
-->
操作効果 (下の GIF 画像):
3. アノテーションメソッドを使用してサーブレットを開発します。
web.xml 構成ファイルの代わりに @WebServlet アノテーションを使用します。例: @WebServlet(urlPatterns = {"/nbServlet", "/nBServlet"})。複数の URL を同時に構成し、同時に有効にすることができます。。
@WebServlet アノテーション クラスのソース コードは次のとおりです。
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package jakarta.servlet.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WebServlet {
String name() default "";
String[] value() default {};
String[] urlPatterns() default {};
int loadOnStartup() default -1;
WebInitParam[] initParams() default {};
boolean asyncSupported() default false;
String smallIcon() default "";
String largeIcon() default "";
String description() default "";
String displayName() default "";
}
@WebServlet アノテーション メソッドを使用する場合、初めて Tomcat にリクエストを送信するときに、Tomcat は IDEA パッケージの下でスキャンします。クラスが @WebServlet アノテーションで変更されていることが判明した場合、そのクラスはクラスであるとみなされます。サーブレット クラスを選択すると、 @WebServlet アノテーションの urlPattern 属性を取得します。注 - Tomcat が @WebServlet を読み取ると、 Servlet の完全なクラス名(フルパス、正しい名前)が取得されます。
残りの手順は、「web.xml」構成と同様です。
Test クラスをデモ クラスとして使用すると、コードは次のようになります。
package advance;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebInitParam;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author : Cyan_RA9
* @version : 21.0
*/
@WebServlet(urlPatterns = {"/TTT", "/tee"},
loadOnStartup = 1,
initParams = {@WebInitParam(name="n1", value="v1"),
@WebInitParam(name = "n2", value = "v2")})
public class Test extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("Test's doGet is invoked");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("Test's doPost is invoked");
}
}
操作効果 (下の GIF 画像):
PS:
WebInitParam アノテーション クラスのソース コードは次のとおりです。
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package jakarta.servlet.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WebInitParam {
String name();
String value();
String description() default "";
}
4. URL マッチングの 4 つの方法:
1°完全一致
例: @WebServlet(urlPatterns={"/TTT", "/tee"})
完全一致モードでは、入力された URL がアノテーションで定義された URL と完全に一致する場合にのみ、サーブレット リソースが正常に見つかります。(推薦する)
2°ディレクトリマッチング
例: @WebServlet("/TTT/*")
ディレクトリ一致モードでは、/* より前のディレクトリと一致する限り、* は後で任意に書き込むことができることを意味し、複数レベルのディレクトリがサポートされます。
3°延長マッチング
例: @WebServlet(" *.action ")
拡張子一致モードでは、指定されたサフィックス名と一致する限り、先頭に任意の文字を記述します。注 -拡張子マッチングを使用する場合、 / を前に置くことはできません。そうしないと、Tomcat がエラーを報告します ( / を使用したマッチングモードと競合します) 。
4° 任意の一致
例: @WebServlet("/") または @WebServlet("/*")
/と/*の構成はすべてのリクエストに一致します (非推奨)
5° Δ注意事項Δ
(1) サーブレットが 「/」 で構成されている場合、Tomcat の DefaultServlet が上書きされ、静的リソースにアクセスできなくなります。(/ は DefaultServlet よりも優先度が高いため、ブラウザによって送信された静的リソースに対するリクエストはサーブレットに対するリクエストと一致します); tomcat/conf/web.xml で DefaultServletのデフォルト設定を確認できます。したがって、任意の一致 / および /* を使用することはお勧めできません。(2) 4 つの URL マッチング モードの優先順位に従います : 正確なパス > ディレクトリ パス > 拡張パス > /* > / > DefaultServlet。
4. サーブレットの概要(その1)
(1)「サーブレットの実装」インターフェースの最も基本的な開発方法を理解する。
(2)サーブレットを要求するブラウザの処理解析を習得する(静的リソースを要求するブラウザの処理解析に問い合わせる)。
(3)サーブレット呼び出しのライフサイクルをよく理解する。
(4)「HttpServletクラスの継承」という開発手法を習得し、その原理を理解する
(5)サーブレットを開発するためのアノテーション方式の使用と、web.xml 方式との違いについて理解します。
System.out.println("END------------------------------------------ --------------------------------------」);