JavaWeb Express サーブレット (サーブレットおよび HttpServlet)

目次

1. サーブレットによるクイックスタート

        1. サーブレットが必要な理由は何ですか?

        2.サーブレットとは何ですか?

        3.サーブレット開発手順: 

        4. はじめるケース: 

2. サーブレットのライフサイクル

        1. サーブレットを要求するブラウザのプロセス分析 (重要): 

        2. ライフサイクル: 

            1° 初期化フェーズ

            2° 処理要求ステージ

            3° 終了フェーズ

3. サーブレットの基本的な使い方

        1. Get リクエストと Post リクエストの処理: 

        2. サーブレット (HttpServlet) を開発するための正しいアプローチ: 

        3. アノテーションメソッドを使用してサーブレットを開発します。 

        4. URL マッチングの 4 つの方法: 

            1°完全一致 

            2°ディレクトリマッチング

            3°延長マッチング

            4° 任意の一致

            5° Δ注意事項Δ

4. サーブレットの概要(その1)


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. サーブレットをリクエストするブラウザのプロセス分析 (重要): 

                 ブラウザはまず URL からホスト名を解析します(例: www.baidu.com)。

                 ブラウザは、ローカル マシンの C:\Windows\System32\drivers\etc ディレクトリにある host ファイルに移動して、ホスト名に対応する IP があるかどうかを確認します。以下に示すように: 

                 ドメイン名に対応する IP が本機の hosts ファイルに見つからない場合は、外部ネットワークの DNS (ドメイン ネーム システム) を参照して検索を続けますが、それでも見つからない場合は、プロンプトが表示されます。次の図に示すように、Web サイトが見つからないことがわかります。 

                ブラウザが hosts ファイルまたは DNS サーバー内のホスト名に対応する IP を正常に見つけると、取得した IP に基づいてTomcat に HTTP リクエストを発行します

                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 コレクションに追加します。

                 次に、Tomcat はサービス メソッドを呼び出し、対応するサーブレット インスタンスがサービスを処理します。アクセス要求ごとに、サーブレットエンジンは新しいHttpServletRequest要求オブジェクトと新しいHttpServletResponse応答オブジェクトを作成し、これら 2 つのオブジェクトをパラメータとして使用します。呼び出すサーブレットのservice()メソッドに渡すとserviceメソッドはリクエスト メソッドに従って doGet | dePost | その他のメソッドを呼び出します。

                6°サーブレット インスタンスが HashMap コレクションで見つかった場合、サーブレットのサービス メソッドが直接呼び出されます。サーブレットがメモリ内に常駐し、シングルトン (インスタンスが 1 つだけ) であることがわかります

               サーブレット インスタンスがサービス メソッドの処理を完了すると、データは HttpServletResponse オブジェクトの形式で Tomcat に返されます

                8° Tomcat は HttpServletResponse オブジェクトを解析してデータを取得し、そのデータを HTTP 応答にパッケージ化して、HTTP 応答の形式でブラウザに返します

                ブラウザは返された結果を解析して表示します。

                追伸: 

                静的 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 クラスのクラス図は次のとおりです。 

                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------------------------------------------ --------------------------------------」);

おすすめ

転載: blog.csdn.net/TYRA9/article/details/131741917