動的 Web サイト開発 04: Servelt の基本

記事ディレクトリ

1. サーブレットの基本

  • 目標: サーブレットの概念、機能、インターフェイスをマスターする

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

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

  • サーブレットは、Java 言語で記述された Web サーバー側で実行される Java アプリケーションです。 Java プログラムとの違いは、サーブレット オブジェクトは主に HTTP リクエストの処理をカプセル化し、その動作にはサーブレット コンテナのサポートが必要であることです。 Java Web アプリケーションの観点から見ると、サーブレット アプリケーションは非常に重要な位置を占めており、Web リクエストの処理においても非常に強力です。

2、Servlet容器

  • サーブレットは、サーブレットコンテナによって提供されます。サーブレットコンテナとは、サーブレット機能を提供するサーバーを指します(この講義ノートでは Tomcat を指します)。サーブレット コンテナは、サーブレットをサーバーに動的にロードします。 HTTP プロトコルに関連するサーブレットは、HTTP 要求および HTTP 応答を使用してクライアントと対話します。したがって、サーブレット コンテナは、すべての HTTP プロトコルのリクエストと応答をサポートします。

3. サーブレットアプリケーションのアーキテクチャ

  • サーブレット リクエストは、最初に HTTP サーバー (Apache など) によって受信されます。HTTP サーバーは静的 HTML ページの解析のみを担当します。サーブレット リクエストはサーブレット コンテナに転送されます。サーブレット コンテナは、次に従って対応するサーブレットを呼び出します。 web.xml ファイル内のマッピング関係を参照すると、サーブレットは処理結果をサーブレット コンテナに返し、HTTP サーバー経由でクライアントに応答を送信します。

(2) サーブレットの特徴

  • サーブレットは Java 言語で記述されており、Java 言語の利点を備えているだけでなく、Web 関連アプリケーションをカプセル化すると同時に、サーブレット コンテナはアプリケーションに関連する拡張機能も提供するため、機能、パフォーマンス、パフォーマンスの点で優れています。セキュリティ等。

1. 強力な機能

  • サーブレットは Java 言語で書かれています。Java API のオブジェクトとメソッドを呼び出すことができます。さらに、サーブレット オブジェクトは Web アプリケーションをカプセル化し、Web アプリケーションにサーブレットのプログラミング インターフェイスを提供し、送信データの処理やセッション トラッキングなど、それに応じて HTTP リクエストを処理することもできます。 、HTTPヘッダー情報などを読み取って設定します。 Servlet は Java が提供する API だけでなく、Servlet でカプセル化された Servlet API プログラミング インターフェイスを呼び出すことができるため、ビジネス機能の点で非常に強力です。

2. ポータブル

  • Java 言語はクロスプラットフォームです。いわゆるクロスプラットフォームとは、プログラムの実行がオペレーティング システム プラットフォームに依存しないことを意味します。現在一般的に使用されているオペレーティング システムである Windows、Linux など、複数のシステム プラットフォーム上で実行できます。そしてUNIX。

3. 高性能

  • サーブレット オブジェクトは、サーブレット コンテナの起動時に初期化されます。サーブレット オブジェクトが初めて要求されると、サーブレット コンテナはサーブレット オブジェクトをインスタンス化します。このとき、サーブレット オブジェクトはメモリ内に存在します。複数のリクエストがある場合、サーブレットは再度インスタンス化されず、他のリクエストは最初にインスタンス化されたサーブレット オブジェクトによって引き続き処理されます。各リクエストはプロセスではなくスレッドです。

4. 高い安全性

  • サーブレットは Java のセキュリティ フレームワークを使用しており、サーブレット コンテナはサーブレットに追加のセキュリティ機能を提供することもでき、そのセキュリティは非常に高いです。

5.拡張可能

  • Java言語はオブジェクト指向プログラミング言語であり、サーブレットはJava言語で記述されているため、オブジェクト指向の利点を持っています。ビジネス ロジック処理では、カプセル化や継承などの機能を通じて、実際のビジネス ニーズを拡張できます。

(3) サーブレットインターフェース

1. サーブレットインターフェース

  • サーブレット テクノロジの開発のために、SUN は一連のインターフェイスとクラスを提供しています。その中で最も重要なものは javax.servlet.Servlet インターフェイスです。サーブレットは、サーブレット インターフェイスを実装するクラスであり、ユーザーのリクエストを受信して​​応答するために Web コンテナによって作成および呼び出されます。

2. サーブレットインターフェースメソッド

メソッド宣言 機能説明
void init(ServletConfig 構成) サーブレットがインスタンス化された後、サーブレット コンテナはこのメソッドを呼び出して初期化作業を完了します。
ServletConfig getServletConfig() サーブレット オブジェクトの構成情報を取得し、サーブレットの ServletConfig オブジェクトを返すために使用されます。
文字列 getServletInfo() サーブレットに関する情報 (作成者、バージョン、著作権情報など) を含む文字列を返します。
void service(ServletRequestリクエスト,ServletResponseレスポンス) ユーザーリクエストへの応答を担当します。このメソッドは、コンテナがクライアントからサーブレットオブジェクトにアクセスするリクエストを受信したときに呼び出されます。コンテナは、クライアントのリクエスト情報を表す ServletRequest オブジェクトと、クライアントへの応答に使用される ServletResponse オブジェクトを構築し、それらをパラメータとして service() メソッドに渡します。 service()メソッドでは、ServletRequestオブジェクトを通じてクライアント関連情報やリクエスト情報を取得でき、リクエスト処理後、ServletResponseオブジェクトのメソッドを呼び出してレスポンス情報を設定します。
無効な破壊() サーブレット オブジェクトによって占有されているリソースを解放します。サーバーがシャットダウンされるか、サーブレット オブジェクトが削除されると、サーブレット オブジェクトは破棄され、コンテナはこのメソッドを呼び出します。

3. サーブレットインターフェースのライフサイクルメソッド

  • サーブレット インターフェイスの 5 つのメソッドのうち、init()、service()、destroy() の 3 つはサーブレットのライフ サイクルを表すことができ、特定の瞬間に呼び出されます。サーブレット コンテナは Web サーバーを指すことに注意してください。

4. サーブレットインターフェースの実装クラス

  • サーブレット インターフェイスの場合、SUN は GenericServlet と HttpServlet という 2 つのデフォルト インターフェイス実装クラスを提供します。 GenericServlet は、Servlet インターフェイスの部分的な実装を提供する抽象クラスであり、HTTP リクエストの処理は実装しません。 HttpServlet は GenericServlet のサブクラスで、GenericServlet のすべてのメソッドを継承し、POST、GET、およびその他の種類の HTTP リクエストに対する特定の操作メソッドを提供します。

5. HttpServlet クラスの共通メソッドと関数

メソッド宣言 機能説明
protected void doGet(HttpServletRequest req, HttpServletResponse resp) GET タイプの HTTP リクエストを処理するメソッド
protected void doPost(HttpServletRequest req, HttpServletResponse resp) POST タイプの HTTP リクエストを処理するメソッド
protected void doPut(HttpServletRequest req, HttpServletResponse resp) PUT タイプの HTTP リクエストを処理するメソッド

2. サーブレット開発の概要

(1) 最初のサーブレットプログラムを実装する

  • 目標: IDEA ツールを使用してサーブレット プログラムを開発する方法をマスターする

1. IDEA を使用してサーブレット開発を完了する

  • 実際の開発ではサーブレットの開発にはIDEA(またはEclipseなど)ツールを使用することが多いですが、IDEAではサーブレットのコンパイルだけでなくweb.xmlファイルの情報も自動で作成してくれるため、IDEAを使用してサーブレットの開発を完了させます。これにより、サーブレット仮想パスのマッピングが完了します。
(1) 新しいWebプロジェクトを作成する
  • IDEA ホームページで [新しいプロジェクトの作成] オプションを選択して、新しいプロジェクト インターフェイスに入ります。
    ここに画像の説明を挿入します

  • 新しいプロジェクト インターフェイスで、左側の列の [Java] オプションを選択し、[Web アプリケーション] オプションをオンにします。選択後、「次へ」ボタンをクリックして、プロジェクト情報を入力するインターフェイスに入ります。
    ここに画像の説明を挿入します

  • 新しいプロジェクト インターフェイスでは、[プロジェクト名] オプションはプロジェクトの名前を参照するために使用され、[プロジェクト ロケーション] オプションは Web プロジェクトのルート ディレクトリを指定するために使用されます。プロジェクトのルート ディレクトリを D:\web_work\chapter04 に設定し、Web プロジェクトの名前として WebDemo を使用します。設定が完了したら、「完了」ボタンをクリックして開発画面に入ります。
    ここに画像の説明を挿入します

  • アーティファクト名の変更 -WebDemo
    ここに画像の説明を挿入します

  • Tomcat サーバー構成の編集
    ここに画像の説明を挿入します

  • [サーバー]タブに切り替えます
    ここに画像の説明を挿入します

  • サーバーを起動して効果を確認する
    ここに画像の説明を挿入します

(2) サーブレットクラスの作成
  • 新しい net.xyx.servlet パッケージを作成する

  • net.xyxi.servlet パッケージにクラスを作成ServletDemo01します

  • この時点で、IDEA ツールはサーブレット コードを自動的に生成します。

  • サーブレットの実行効果をより適切に示すために、次に、ServletDemo01 の doGet() メソッドと doPost() メソッドにコードを追加します。 @WebServlet アノテーションに urlPatterns 属性値を設定します: urlPatterns = "/demo01"

package net.xyx.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 功能:Servlet演示类
 * 作者:xyx
 * 日期:2023年03月12日
 */
@WebServlet(name = "ServletDemo01", urlPatterns = "/demo01")
public class ServletDemo01 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 获取字符输出流
        PrintWriter out = response.getWriter();
        // 输出信息
        out.print("<h1>Hello Servlet World~</h1>");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }
}
  • 実際、サーブレットは本質的には Java プログラムに埋め込まれた HTML ページです。
(3) サーブレットの起動
  • サーバーを起動してホームページを表示する

  • ページ上のServletDemo01クラスのURLアドレス「localhost:8080/WebDemo/demo01」にアクセスします。

  • 対応図

  • 赤いメッセージを表示して中央に表示したい場合は、スタイルを使用する必要があります

2. 授業演習 - Web プロジェクトを作成し、サーブレットを使用して個人情報を表示する

  • Java エンタープライズ プロジェクトを作成する

  • プロジェクト名と保存場所を設定する

  • [完了]ボタンをクリックします

  • アーティファクトの名前を表示する

  • 名前を「ShowInfo」に変更します

  • Tomcatサーバーを構成する

  • デプロイメントの ShowInfo を削除し、再度追加します

  • [サーバー]タブに切り替えてURLを表示します。

  • Tomcatサーバーを起動して効果を確認する

  • 個人情報を表形式で表示するようにホームページ ファイルを変更する

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>个人信息</title>
    </head>
    <body>
        <table style="text-align: center" border="1" align="center" cellpadding="5">
            <tr>
                <td>学号</td>
                <td>姓名</td>
                <td>性别</td>
                <td>年龄</td>
                <td>专业</td>
                <td>班级</td>
                <td>手机</td>
            </tr>
            <tr>
                <td>20210201</td>
                <td>陈燕文</td>
                <td></td>
                <td>18</td>
                <td>软件技术专业</td>
                <td>2021软件2班</td>
                <td>15890456780</td>
            </tr>
        </table>
    </body>
</html>
  • サーバーを起動して結果を表示する

  • net.huawei.servlet パッケージを作成し、そのパッケージ内に InfoServlet クラスを作成します。

package net.xyx.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 功能:显示个人信息
 * 作者:xyx
 * 日期:2023年03月31日
 */
@WebServlet(name = "InfoServlet", urlPatterns = "/info")
public class InfoServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 获取字符输出流
        PrintWriter out = response.getWriter();
        // 往客户端输出信息
        out.print("<!DOCTYPE html>");
        out.print("<html>");
            out.print("<head>");
                out.print("<meta charset='UTF-8'");
                out.print("<title>个人信息</title>");
            out.print("</head>");
            out.print("<body style='text-align: center'>");
                out.print("<table border='1' align='center' cellpadding='5'>");
                    out.print("<tr>");
                        out.print("<td>学号</td>");
                        out.print("<td>姓名</td>");
                        out.print("<td>性别</td>");
                        out.print("<td>年龄</td>");
                        out.print("<td>专业</td>");
                        out.print("<td>班级</td>");
                        out.print("<td>手机</td>");
                    out.print("</tr>");
                    out.print("<tr>");
                        out.print("<td>20210201</td>");
                        out.print("<td>陈燕文</td>");
                        out.print("<td></td>");
                        out.print("<td>18</td>");
                        out.print("<td>软件技术专业</td>");
                        out.print("<td>2021软件2班</td>");
                        out.print("<td>15890456780</td>");
                        out.print("</tr>");
                out.print("</table>");
            out.print("</body>");
        out.print("</html>");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }
}
  • Tomcat サーバーを起動し、http://localhost:8080/ShowInfo/info にアクセスします。

  • ページ上に中国語の文字化けが表示されるため、文字エンコードの設定が必要です(Chromeブラウザのデフォルトの文字エンコードを確認する必要があります)

  • 応答オブジェクトの文字エンコーディングを、ブラウザで現在使用されている文字エンコーディングと一致する UTF-8 に設定します。

  • Tomcat サーバーを再起動し、http://localhost:8080/ShowInfo/info にアクセスします。

  • ブラウザーで現在使用されている文字エンコーディングに関係なく、ブラウザーが指定された文字エンコーディングを使用することを要求するように応答オブジェクトのコンテンツ タイプを設定します。

  • Tomcat サーバーを再起動し、http://localhost:8080/ShowInfo/info にアクセスします。

  • 現在ブラウザで使用されている文字コードを確認してください GBKに変更されています。

(2) サーブレットの構成

  • 目的: サーブレット構成を完了する 2 つの方法をマスターします。Web アプリケーション構成ファイル web.xml を使用する方法と、@WebServlet アノテーションを使用してサーブレット構成を完了する方法です。
  • サーブレットをサーバー内で正しく実行し、リクエスト情報を処理するには、適切な構成を実行する必要があります。サーブレットを構成するには、主に 2 つの方法があります。1 つは Web アプリケーションの構成ファイル web.xml を使用する方法、もう 1 つは @WebServlet を使用する方法です。注釈を付けて完成させる方法です。

1. web.xml を使用してサーブレットを構成する

  • web.xml ファイルでは、登録はタグを通じて行われ、タグの下にいくつかのサブ要素が含まれます。
属性名 タイプ 説明
<servlet-name> 文字列はサーブレットの名前を指定します。これは通常、サーブレット クラス名と同じであり、一意である必要があります。
<servlet-class> パッケージ名とクラス名を含むサーブレット クラスの場所を文字列で指定します。
<description> サーブレットの説明情報を文字列で指定します。
<display-name> サーブレットの表示名を文字列で指定します。
  • サーブレットを URL アドレスにマッピングし、マッピングにタグを使用し、サブタグを使用してマッピングするサーブレットの名前を指定します。名前は、タグの下に以前に登録したものと同じである必要があります。サブタグを使用して URL をマッピングします。アドレスの場合は、アドレスの前に「/」を追加する必要があります。それ以外の場合は、「未満」にアクセスします。

  • デプロイメント記述ファイル web.xml にサーブレットを登録した後、InfoServlet クラスの注釈をコメント アウトできます。

  • Tomcatサーバーを再起動してアクセスします。http://localhost:8080/ShowInfo/info

2. @WebServlet アノテーション属性

  • @WebServlet アノテーションは、web.xml ファイル内の他のタグを置き換えるために使用されます。このアノテーションは、プロジェクトのデプロイメント中にコンテナーによって処理され、コンテナーは、特定の属性構成に基づいて、対応するクラスをサーブレットとしてデプロイします。この目的のために、@WebServlet アノテーションはいくつかのプロパティを提供します。
プロパティの宣言 機能説明
文字列名 サーブレットの name 属性を指定します。これは と同等です。明示的に指定しない場合、
Servlet の値は、クラスの完全修飾名です。
文字列[]値 この属性は、u​​rlPatterns 属性と同等です。 urlPatterns 属性と value 属性を同時に使用することはできません。
文字列[] URLパターン サーブレット URL 一致パターンのセットを指定します。ラベルに相当します。
intloadOnStartup サーブレットのロード順序を指定します。これはラベルに相当します。
WebInitParam[] タグに相当するサーブレット初期化パラメータのセットを指定します。
ブール値非同期サポートあり サーブレットがタグに相当する非同期操作モードをサポートするかどうかを宣言します。
文字列の説明 サーブレットの説明情報がラベルに相当します。
文字列displayName ervlet の表示名は通常ツールで使用され、ラベルと同等です。
@WebServlet アノテーションは、HttpServlet クラスを継承する任意のクラスに付けることができ、クラスレベルのアノテーションです。次に、@WebServlet アノテーションを使用して InfoServlet クラスにアノテーションを付けます。
  • web.xml ファイル内の InfoServlet の登録タグをコメントアウトします。

  • Tomcat サーバーを再起動し、http://localhost:8080/ShowInfo/info にアクセスします。

  • @WebServlet アノテーションを使用して、InfoServlet クラスをサーブレットとしてマークします。 @WebServlet アノテーションの name 属性値は、サーブレットの name 属性を指定するために使用されます。同様に、@WebServlet の name 属性が設定されていない場合、そのデフォルト値はサーブレットの完全なクラス名です。 urlPatterns 属性値は、ラベルに相当するサーブレット URL 一致パターンのセットを指定するために使用されます。 @WebServlet アノテーションで複数のプロパティを設定する必要がある場合は、それらをカンマで区切ります。 @WebServlet アノテーションにより、サーブレットの構成手順が大幅に簡素化され、開発者の開発の困難さが軽減されます。

3. サーブレットの複数の URL を構成する

  • 人が複数の外部連絡手段を持っているようなものです

  • サーバーを起動してアクセスするhttp://localhost:8080/ShowInfo/info

  • アクセスhttp://localhost:8080/ShowInfo/message

(3) サーブレットのライフサイクル

  • 目標: サーブレットの 3 つのライフ サイクル、初期化フェーズ、実行フェーズ、破棄フェーズをマスターする

1. サーバーのライフサイクル - 初期化フェーズ

  • クライアントがサーブレットにアクセスするために HTTP リクエストをサーブレット コンテナに送信すると、サーブレット コンテナは最初にリクエストを解析し、サーブレット オブジェクトがメモリ内にすでに存在するかどうかを確認します。存在する場合は、サーブレット オブジェクトを直接使用します。存在しない場合は、サーブレット オブジェクトを直接使用します。サーブレット インスタンス オブジェクトを指定し、init() メソッドを呼び出してサーブレットの初期化を完了します。サーブレットのライフサイクル全体を通じて、その init() メソッドは 1 回だけ呼び出されることに注意してください。

2. サーブレットのライフサイクル - 実行フェーズ

  • これは、サーブレットのライフ サイクルで最も重要な段階です。この段階では、サーブレット コンテナは、HTTP リクエストを表す ServletRequest オブジェクトと、クライアント リクエストに対する HTTP レスポンスを表す ServletResponse オブジェクトを作成し、それらをパラメータとしてサーブレットのservice() メソッドです。 service() メソッドは、ServletRequest オブジェクトからクライアント要求情報を取得して処理し、ServletResponse オブジェクトを通じて応答結果を生成します。サーブレットのライフ サイクル全体を通じて、サーブレットのアクセス要求ごとに、サーブレット コンテナはサーブレットの service() メソッドを 1 回呼び出し、新しい ServletRequest オブジェクトと ServletResponse オブジェクトを作成します。サーブレットの存続期間全体を通じて使用され、サイクル中に複数回呼び出されます。

3. サーブレットのライフサイクル - 破棄フェーズ

  • サーバーがシャットダウンされるか、Web アプリケーションがコンテナから削除されると、サーブレットは Web アプリケーションとともに破棄されます。サーブレットを破棄する前に、サーブレット コンテナはサーブレットの destroy() メソッドを呼び出して、サーブレット オブジェクトが占有しているリソースを解放できるようにします。サーブレットのライフサイクル全体で、destroy() メソッドは 1 回だけ呼び出されます。サーブレット オブジェクトが作成されると、メモリ内に常駐してクライアントのアクセスを待ちます。サーブレット オブジェクトは、サーバーがシャットダウンされるか、Web アプリケーションがコンテナから削除されるまで破棄されません。

4. 事例デモ サーブレットのライフサイクル

  • WebDemo プロジェクトで ServletDemo02 クラスを作成し、ServletDemo02 クラスで init() メソッドと destroy() メソッドを記述し、ケースを使用してサーブレット ライフ サイクル メソッドの実行効果を実証するために service() メソッドをオーバーライドします。
package net.xyx.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 功能:演示Servlet生命周期
 * 作者:xyx
 * 日期:2023年03月12日
 */
@WebServlet(name = "ServletDemo02", value = "/demo02")
public class ServletDemo02 extends HttpServlet {
    @Override
    public void init() throws ServletException {
        System.out.println("init()方法被调用……");
    }

    protected void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("service()方法被调用……");
        response.setContentType("text/html; charset=utf-8");
        PrintWriter out = response.getWriter();
        out.print("<h1>演示Servlet生命周期~</h1>");
    }

    @Override
    public void destroy() {
        System.out.println("destroy()方法被调用……");
    }
}
  • Tomcatサーバーを起動してアクセスします。http://localhost:8080/WebDemo/demo02

  • ブラウザを 2 回更新し、ServletDemo02 に 2 回アクセスして、Tomcat コンソールの印刷結果を表示します。

  • init() メソッドは最初のアクセス時にのみ実行され、service() メソッドはアクセスごとに実行されます。

  • ServletDemo02 を削除する場合は、IDEA で WebDemo プロジェクトを停止できます。このとき、サーブレット コンテナは ServletDemo02 の destroy() メソッドを呼び出し、「destroy() メソッドが呼び出されました...」というメッセージを画面に出力します。 IDEAコンソール。

  • たとえば、人間は一度しか生まれず(init() メソッド)、一度死ぬだけ(destroy() メソッド)、社会にさまざまなサービスを提供するために途中で何度も転職できます(service() メソッド)。

3. ServletConfig と ServletContext

(1) ServletConfigインターフェース

  • 目標: ServletConfig を使用して構成情報を取得する方法をマスターする

1. ServletConfig インターフェース

  • サーブレットの実行中に、ファイルで使用されるエンコーディングなどの構成情報が必要になることがよくあります。この情報は、@WebServlet アノテーションのプロパティで構成できます。 Tomcat はサーブレットを初期化するときに、サーブレットの構成情報を ServletConfig オブジェクトにカプセル化し、init(ServletConfig config) メソッドを呼び出して ServletConfig オブジェクトをサーブレットに渡します。 ServletConfig は、構成情報を取得するための一連のメソッドを定義します。
メソッドの説明 機能説明
String getInitParameter(文字列名) 初期化パラメータ名に基づいて、対応する初期化パラメータ値を返します。
列挙体 getInitParameterNames() すべての初期化パラメータ名を含む Enumeration オブジェクトを返します。
サーブレットコンテキスト getServletContext() 現在の Web アプリケーションを表す ServletContext オブジェクトを返します。
文字列 getServletName() サーブレットの名前を返します。

2. 事例デモ ServletConfig メソッド呼び出し

  • getInitParameter() メソッドを例として、ServletConfig メソッドの呼び出しを説明します。
  • WebDemo プロジェクトの net.huawei.servlet パッケージに ServletDemo03 クラスを作成します。
package net.xyx.servlet;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;

/**
 * 功能:演示ServletConfig方法的调用
 * 作者:xyx
 * 日期:2023年03月31日
 */
@WebServlet(name = "ServletDemo03", urlPatterns = "/demo03",
    initParams = {@WebInitParam(name="encoding", value = "utf-8"),
                  @WebInitParam(name="text-color", value = "red"),
                  @WebInitParam(name="font-size", value= "25")})
public class ServletDemo03 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 设置响应对象内容类型
        response.setContentType("text/html; charset=utf-8");
        // 获取打印输出流
        PrintWriter out = response.getWriter();
        // 获取Servlet配置对象
        ServletConfig config = getServletConfig();
        // 获取初始化参数名枚举对象
        Enumeration<String> initParams = config.getInitParameterNames();
        // 遍历初始化参数名枚举对象,输出参数名及其值
        while (initParams.hasMoreElements()) {
            String initParam = initParams.nextElement();
            out.print(initParam + " : " + config.getInitParameter(initParam) + "<br />");
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }
}

Tomcat サーバーを起動し、http://localhost:8080/WebDemo/demo03 にアクセスします。

(二)ServletContext接口
目标:掌握ServletContext接口的使用方法
1、获取Web应用程序的初始化参数
当Servlet容器启动时,会为每个Web应用创建一个唯一的ServletContext对象代表当前Web应用。ServletContext对象不仅封装了当前Web应用的所有信息,而且实现了多个Servlet之间数据的共享。
在web.xml文件中,可以配置Servlet的初始化信息,还可以配置整个Web应用的初始化信息。Web应用初始化参数的配置方式具体如下所示。

参数名
参数值


参数名
参数值

1
2
3
4
5
6
7
8

  • <context-param>元素位于根元素<web-app>中,它的子元素<param-name><param-value>分别用来指定参数的名字和参数值。可以通过调用ServletContext接口中定义
  • getInitParameterNames()和getInitParameter(String name)方法,分别获取参数名和参数值。

2、案例演示获取Web应用的容器初始化参数

  • 在WebDemo项目的web.xml文件中,配置容器初始化参数信息和Servlet信息
<?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">

    <context-param>
        <param-name>college</param-name>
        <param-value>泸州职业技术学院</param-value>
    </context-param>
    <context-param>
        <param-name>address</param-name>
        <param-value>泸州市龙马潭区长桥路2号</param-value>
    </context-param>
    <context-param>
        <param-name>secretary</param-name>
        <param-value>何杰</param-value>
    </context-param>
    <context-param>
        <param-name>president</param-name>
        <param-value>谢鸿全</param-value>
    </context-param>
</web-app>
  • 在net.huawei.servlet包里创建ServletDemo04
package net.xyx.servlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;

/**
 * 功能:获取Web应用的容器初始化参数
 * 作者:xyx
 * 日期:2023年03月31日
 */
@WebServlet(name = "ServletDemo04", urlPatterns = "/demo04")
public class ServletDemo04 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 设置响应对象内容类型
        response.setContentType("text/html; charset=utf-8");
        // 获取打印输出流
        PrintWriter out = response.getWriter();
        // 获取Servlet容器对象
        ServletContext context = getServletContext();
        // 获取容器的初始化参数名枚举对象
        Enumeration<String> paramNames = context.getInitParameterNames();
        // 通过循环遍历显示全部参数名与参数值
        while (paramNames.hasMoreElements()) {
            // 获取参数名
            String name = paramNames.nextElement();
            // 按参数名获取参数值
            String value = context.getInitParameter(name);
            // 输出参数名和参数值
            out.print(name + " : " + value + "<br />");
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }
}
  • 启动tomcat服务器,访问http://localhost:8080/WebDemo/demo04

3、实现多个Servlet对象共享数据

  • 由于一个Web应用中的所有Servlet共享同一个ServletContext对象,所以ServletContext对象的域属性可以被该Web应用中的所有Servlet访问。ServletContext接口中定义了用于增加、删除、设置ServletContext域属性的四个方法。
方法说明 功能描述
Enumeration getAttributeNames() 返回一个Enumeration对象,该对象包含了所有存放在ServletContext中的所有域属性名
Object getAttibute(String name) 根据参数指定的属性名返回一个与之匹配的域属性值
void removeAttribute(String name) 根据参数指定的域属性名,从ServletContext中删除匹配的域属性
void setAttribute(String name,Object obj) 设置ServletContext的域属性,其中name是域属性名,obj是域属性值

4、案例演示多个Servlet对象共享数据

  • 在net.xyx.servlet包里创建ServletDemo05
package net.xyx.servlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 功能:写入域属性
 * 作者:xyx
 * 日期:2023年03月31日
 */
@WebServlet(name = "ServletDemo05", urlPatterns = "/demo05")
public class ServletDemo05 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 设置响应对象内容类型
        response.setContentType("text/html; charset=utf-8");
        // 获取Servlet容器对象
        ServletContext context = getServletContext();
        // 写入域属性
        context.setAttribute("id", "20210201");
        context.setAttribute("name", "陈雅雯");
        context.setAttribute("gender", "女");
        context.setAttribute("age", "18");
        context.setAttribute("major", "软件技术专业");
        context.setAttribute("class", "2021软件2班");
        context.setAttribute("telephone", "15890903456");
        // 获取打印输出流
        PrintWriter out = response.getWriter();
        // 输出提示信息
        out.print("<h3>成功地写入了域属性~</h3>");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }
}
  • 在net.xyx.servlet包里创建ServletDemo06
package net.xyxx.servlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;

/**
 * 功能:读取域属性
 * 作者:xyx
 * 日期:2023年03月31日
 */
@WebServlet(name = "ServletDemo06", urlPatterns = "/demo06")
public class ServletDemo06 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 设置响应对象内容类型
        response.setContentType("text/html; charset=utf-8");
        // 获取打印输出流
        PrintWriter out = response.getWriter();
        // 获取Servlet容器对象
        ServletContext context = getServletContext();
        // 获取全部域属性名枚举对象
        Enumeration<String> attributeNames = context.getAttributeNames();
        // 通过循环显示域属性名与域属性值
        while (attributeNames.hasMoreElements()) {
            // 获取域属性名
            String name = attributeNames.nextElement();
            // 获取域属性值
            Object value = context.getAttribute(name);
            // 输出域属性名与域属性值
            out.print(name + " : " + value + "<br />");
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }
}
  • 启动tomcat服务器,先访问http://localhost:8080/WebDemo/demo05

  • 再访问http://localhost:8080/WebDemo/demo06

  • 有很多域属性不是我们写入的,如果我们只想显示我们写入的域属性,那么我们就要修改一下ServletDemo06的代码

  • 重启服务器,访问http://localhost:8080/WebDemo/demo05

  • 再访问http://localhost:8080/WebDemo/demo06

5、读取Web应用下的资源文件

  • ServletContext接口定义了一些读取Web资源的方法,这些方法是依靠Servlet容器来实现的。
  • Servlet容器根据资源文件相对于Web应用的路径,返回关联资源文件的IO流、资源文件在文件系统的绝对路径等。
方法说明 功能描述
Set getResourcePaths(String path) 返回一个Set集合,集合中包含资源目录中子目录和文件的路径名称。参数path必须以正斜线(/)开始,指定匹配资源的部分路径
String getRealPath(String path) 返回资源文件在服务器文件系统上的真实路径(文件的绝对路径)。参数path代表资源文件的虚拟路径,它应该以正斜线(/)开始,“/”表示当前Web应用的根目录,如果Servlet容器不能将虚拟路径转换为文件系统的真实路径,则返回null
URL getResource(String path) 返回映射到某个资源文件的URL对象。参数path必须以正斜线(/)开始,“/”表示当前Web应用的根目录
InputStream getResourceAsStream(String path) 返回映射到某个资源文件的InputStream输入流对象。参数path传递规则和getResource()方法完全一致

6、案例演示读取Web应用下的资源文件

  • 在net.xyx.servlet包里创建属性文件 - college.properties
name = 泸州职业技术学院
address = 泸州市龙马潭区长桥路2号
secretary = 何杰
president = 谢鸿全
  • 在net.xyxservlet包里创建ServletDemo07
package net.xyx.servlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Properties;

/**
 * 功能:读取资源文件
 * 作者:xyx
 * 日期:2023年03月13日
 */
@WebServlet(name = "ServletDemo07", urlPatterns = "/demo07")
public class ServletDemo07 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 设置内容类型
        response.setContentType("text/html; charset=utf-8");
        // 获取Servlet容器对象
        ServletContext context = getServletContext();
        // 获取打印输出流
        PrintWriter out = response.getWriter();
        // 读取资源文件,得到字节输入流
        InputStream in = context.getResourceAsStream(
                "/WEB-INF/classes/net/huawei/servlet/college.properties");
        // 创建属性对象(Map接口的实现类)
        Properties pros = new Properties();
        // 属性对象加载资源文件的资源文件输入流
        pros.load(in);
        // 往客户端输出属性值
        out.println("name = " + pros.getProperty("name") + "<br />");
        out.println("address = " + pros.getProperty("address") + "<br />");
        out.println("secretary = " + pros.getProperty("secretary") + "<br />");
        out.println("president = " + pros.getProperty("president") + "<br />");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }
}
  • 启动tomcat服务器,访问http://localhost:8080/WebDemo/demo07

  • 属性文件的路径问题

  • 读取属性文件得到的字节流编码是ISO-8859-1,需要做一个转码处理

  • 重启tomcat服务器,先访问http://localhost:8080/WebDemo/demo07

  • 在Web项目开发中开发者可能需要获取资源的绝对路径。通过调用getRealPath(String path)方法获取资源文件的绝对路径。

  • 在net.xyx.servlet包里创建ServletDemo08类

package net.xyx.servlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 功能:获取资源的绝对路径
 * 作者:xyx
 * 日期:2023年03月13日
 */
@WebServlet(name = "ServletDemo08", urlPatterns = "/demo08")
public class ServletDemo08 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 获取Servlet容器对象
        ServletContext context = getServletContext();
        // 获取打印输出流
        PrintWriter out = response.getWriter();
        // 创建资源路径字符串
        String path = "/WEB-INF/classes/net/huawei/servlet/college.properties";
        // 获取资源绝对路径
        String realPath = context.getRealPath(path);
        // 输出资源绝对路径
        out.println("college.properties: " + realPath);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }
}
  • 重启tomcat服务器,访问http://localhost:8080/WebDemo/demo08

四、HttpServletResponse对象

(一)发送状态码相关的方法

  • 目标:掌握HttpServletResponse接口定义的3个发送状态码的方法
    当Servlet向客户端回送响应消息时,需要在响应消息中设置状态码,状态码代表着客户端请求服务器的结果。为此,HttpServletResponse接口定义了3个发送状态码的方法。

1、HttpServletResponse接口—setStatus(int status)方法

  • setStatus(int status)方法用于设置HTTP响应消息的状态码,并生成响应状态行。由于响应状态行中的状态描述信息直接与状态码相关,而HTTP版本由服务器确定,所以,只要通过setStatus(int status)方法设置了状态码,即可实现状态行的发送。例如,正常情况下,Web服务器会默认产生一个状态码为200的状态行。

2、HttpServletResponse接口—sendError(int sc)方法

  • sendError(int sc)方法用于发送表示错误信息的状态码,例如,404状态码表示找不到客户端请求的资源。

3、HttpServletResponse接口—sendError(int code,String message)方法

  • sendError(int code, String message)方法除了设置状态码,还会向客户端发出一条错误信息。服务器默认会创建一个HTML格式的错误服务页面作为响应结果,其中包含参数message指定的文本信息,这个HTML页面的内容类型为“text/html”,保留cookies和其他未修改的响应头信息。如果一个对应于传入的错误码的错误页面已经在web.xml中声明,那么这个声明的错误页面会将优先建议的message参数服务于客户端。

(二)发送响应头相关的方法

  • 目标:掌握HttpServletResponse接口设置HTTP响应头字段的方法
方法说明 功能描述
void addHeader(String name, String value) 用来设置HTTP协议的响应头字段,其中,参数name用于指定响应头字段的名称,参数value用于指定响应头字段的值。addHeader()方法可以增加同名的响应头字段
void setHeader(String name, String value) 用来设置HTTP协议的响应头字段,其中,参数name用于指定响应头字段的名称,参数value用于指定响应头字段的值。setHeader()方法则会覆盖同名的头字段
void addIntHeader(String name, int value) 专门用于设置包含整数值的响应头。避免了调用addHeader()方法时,需要将int类型的设置值转换为String类型的麻烦
void setIntHeader(String name, int value) 专门用于设置包含整数值的响应头。避免了调用setHeader()方法时,需要将int类型的设置值转换为String类型的麻烦
void setContentLength(int len) 该方法用于设置响应消息的实体内容的大小,单位为字节。对于HTTP协议来说,这个方法就是设置Content-Length响应头字段的值
void setContentType(String type) 该方法用于设置Servlet输出内容的MIME类型,对于HTTP协议来说,就是设置Content-Type响应头字段的值。例如,如果发送到客户端的内容是jpeg格式的图像数据,就需要将响应头字段的类型设置为“image/jpeg”。需要注意的是,如果响应的内容为文本,setContentType()方法的还可以设置字符编码,如:text/html;charset=UTF-8
void setLocale(Locale loc) 该方法用于设置响应消息的本地化信息。对HTTP来说,就是设置Content-Language响应头字段和Content-Type头字段中的字符集编码部分。需要注意的是,如果HTTP消息没有设置Content-Type头字段,setLocale()方法设置的字符集编码不会出现在HTTP消息的响应头中,如果调用setCharacterEncoding()或setContentType()方法指定了响应内容的字符集编码,setLocale()方法将不再具有指定字符集编码的功能
void setCharacterEncoding(String charset) 该方法用于设置输出内容使用的字符编码,对HTTP 协议来说,就是设置Content-Type头字段中的字符集编码部分。如果没有设置Content-Type头字段,setCharacterEncoding方法设置的字符集编码不会出现在HTTP消息的响应头中。setCharacterEncoding()方法比setContentType()和setLocale()方法的优先权高,setCharacterEncoding()方法的设置结果将覆盖setContentType()和setLocale()方法所设置的字符码表
  • 需要注意的是,addHeader()、setHeader()、addIntHeader()、setIntHeader()方法都是用于设置各种头字段的,而setContetType()、setLoacale()和setCharacterEncoding()方法用于设置字符编码,这些设置字符编码的方法可以有效解决中文字符乱码问题。

(三)发送响应消息体相关的方法

  • 目标:掌握发送响应消息体相关的方法getOutputStream()和getWriter()
  • 由于在HTTP响应消息中,大量的数据都是通过响应消息体传递的,所以,ServletResponse遵循IO流传递大量数据的设计理念。在发送响应消息体时,定义了两个与输出流相关的方法。

1、getOutputStream()方法

  • getOutputStream()方法所获取的字节输出流对象为ServletOutputStream类型。由于ServletOutputStream是OutputStream的子类,它可以直接输出字节数组中的二进制数据。所以,要想输出二进制格式的响应正文,就需要调用getOutputStream()方法。

2、getWriter()方法

getWriter()方法所获取的字符输出流对象为PrintWriter类型。由于PrintWriter类型的对象可以直接输出字符文本内容,所以,要想输出内容为字符文本的网页文档,需要调用getWriter()方法。

3、案例演示发送响应消息体

  • 创建net.xyx.response包

  • 在net.xyx.response包里创建PrintServlet01类

package net.huawei.response;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;

/**
 * 功能:演示响应体输出字节流
 * 作者:xyx
 * 日期:2023年04月07日
 */
@WebServlet(name = "PrintServlet01", urlPatterns = "/print01")
public class PrintServlet01 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 定义字符串数据
        String data = "欢迎访问泸州职业技术学院~";
        // 获取字节输出流对象
        OutputStream out = response.getOutputStream();
        // 往客户端输出信息
        out.write(data.getBytes());
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }
}
  • 重启tomcat服务器,访问http://localhost:8080/WebDemo/print01

  • 在net.xyx.response包里创建PrintServlet02

package net.xyx.response;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 功能:演示响应体打印字符流
 * 作者:xyx
 * 日期:2023年04月07日
 */
@WebServlet(name = "PrintServlet02", urlPatterns = "/print02")
public class PrintServlet02 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 定义字符串数据
        String data = "欢迎访问泸州职业技术学院~";
        // 获取打印字符流
        PrintWriter out = response.getWriter();
        // 往客户端输出信息
        out.println(data);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }
}
  • 重启tomcat服务器,访问http://localhost:8080/WebDemo/print02

  • 为了解决页面中文乱码问题,要修改代码

  • 重启tomcat服务器,访问http://localhost:8080/WebDemo/print02

五、HttpServletResponse应用

(一)实现请求重定向

  • 目标:掌握HttpServletResponse接口的sendRedirect()方法,实现请求重定向
    在某些情况下,针对客户端的请求,一个Servlet类可能无法完成全部工作。这时,可以使用请求重定向来完成。所谓请求重定向,指的是Web服务器接收到客户端的请求后,可能由于某些条件限制,不能访问当前请求URL所指向的Web资源,而是指定了一个新的资源路径,让客户端重新发送请求。

1、HttpServletResponse接口—sendRedirect()方法

  • 为了实现请求重定向,HttpServletResponse接口定义了一个sendRedirect()方法,该方法用于生成302响应码和Location响应头,从而通知客户端重新访问Location响应头中指定的URL。
    sendRedirect()方法的完整声明:public void sendRedirect(java.lang.String location) throws java.io.IOException
  • 需要注意的是,参数location可以使用相对URL,Web服务器会自动将相对URL翻译成绝对URL,再生成Location头字段。
  • sendRedirect()方法的工作原理

2、案例演示实现请求重定向

  • 创建登录页面 - login.html
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>用户登录</title>
    </head>
    <body>
        <form action="login" method="post">
            <fieldset>
                <legend>用户登录</legend>
                <table cellpadding="2" align="center">
                    <tr>
                        <td align="right">用户名:</td>
                        <td>
                            <input type="text" name="username"/>
                        </td>
                    </tr>
                    <tr>
                        <td align="right">密码:</td>
                        <td>
                            <input type="password" name="password"/>
                        </td>
                    </tr>
                    <tr>
                        <td colspan="2" align="center">
                            <input type="submit" value="登录"/>
                            <input type="reset" value="重置"/>
                        </td>
                    </tr>
                </table>
            </fieldset>
        </form>
    </body>
</html>
  • 创建欢迎页面 - welcome.html
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>登录成功</title>
    </head>
    <body>
        <h3 style="text-align: center">欢迎你,登录成功~</h3>
    </body>
</html>
  • 在net.xyx.response包里创建LoginServlet类,处理用户登录请求
package net.xyx.response;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 功能:登录处理程序
 * 作者:xyx
 * 日期:2023年04月07日
 */
@WebServlet(name = "LoginServlet", urlPatterns = "/login")
public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        // 设置响应体内容类型
        response.setContentType("text/html; charset=utf-8");
        // 获取登录表单提交的用户名和密码
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        // 判断是否登录成功,决定重定向到不同页面
        if ("howard".equals(username) && "903213".equals(password)) {
            // 重定向到欢迎页面
            response.sendRedirect("/WebDemo/welcome.html");
        } else {
            // 重定向到登录页面
            response.sendRedirect("/WebDemo/login.html");
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        doPost(request, response);
    }
}
  • 重启tomcat服务器,访问http://localhost:8080/WebDemo/login.html

  • 在login.html页面填写用户名“howard”,密码“903213”

  • 单击登录按钮,跳转到欢迎页面

  • 录屏操作演示

(二)动手实践:解决中文输出乱码问题

  • 目标:掌握如何解决中文输出乱码问题

1、中文乱码问题

  • 由于计算机中的数据都是以二进制形式存储的,所以,当传输文本时,就会发生字符和字节之间的转换。字符与字节之间的转换是通过查码表完成的,将字符转换成字节的过程称为编码,将字节转换成字符的过程称为解码,如果编码和解码使用的码表不一致,就会导致乱码问题。

2、案例演示解决乱码问题

在net.xyx.response包里创建ChineseServlet

package net.xyx.response;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 功能:演示解决中文乱码问题
 * 作者:xyx
 * 日期:2023年03月13日
 */
@WebServlet(name = "ChineseServlet", urlPatterns = "/chinese")
public class ChineseServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {        
        // 创建数据字符串
        String data = "欢迎访问泸州职业技术学院~";
        // 获取打印字符输出流
        PrintWriter out = response.getWriter();
        // 在页面输出信息
        out.println(data);        
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }
}```
- 重启tomcat服务器,访问`http://localhost:8080/WebDemo/chinese`
![在这里插入图片描述](https://img-blog.csdnimg.cn/3753008021754cc7920353c6cc2bf59c.png)


- 浏览器显示的内容都是“???~”,说明发生了乱码问题。此处产生乱码的原因是response对象的字符输出流在编码时,采用的是ISO-8859-1的字符码表,该码表并不兼容中文,会将“欢迎访问泸州职业技术学院”编码为“63 63 63 63 63 63 63 63 63 63 63 63”(在ISO-8859-1的码表中查不到的字符就会显示63)。当浏览器对接收到的数据进行解码时,会采用默认的码表GB2312,将“63 ”解码为“?”,因此,浏览器将“欢迎访问泸州职业技术学院”十二个字符显示成了“???”。

- 解决页面乱码问题

- `HttpServletResponse`接口提供了一个`setCharacterEncoding()`方法,该方法用于设置字符的编码方式,接下来对`ChineseServlet`类进行修改,在代码String data = "欢迎访问泸州职业技术学院~";前增加一行代码,设置字符编码使用的码表为utf-8。
![在这里插入图片描述](https://img-blog.csdnimg.cn/32a6839c1db04258ab530e61cfaf0016.png)


- 重启tomcat服务器,访问`http://localhost:8080/WebDemo/chinese`

![在这里插入图片描述](https://img-blog.csdnimg.cn/48e9a1a0e1f546668a6d10a43571a91e.png)

- 浏览器中显示的乱码虽然不是`“????????????~`”,但也不是需要输出的“欢迎访问泸州职业技术学院~”,这是由于浏览器解码错误导致的。`response`对象的字符输出流设置的编码方式为UTF-8,而浏览器使用的解码方式是GBK。
![在这里插入图片描述](https://img-blog.csdnimg.cn/add083a55c9e4b7aa610a2d40b99db2d.png)


- 将`response`对象的字符输出流设置的编码方式改为GBK
![在这里插入图片描述](https://img-blog.csdnimg.cn/840004418f7445d8aa98e20b05f76f9d.png)


- 重启tomcat服务器,访问`http://localhost:8080/WebDemo/chinese`
![在这里插入图片描述](https://img-blog.csdnimg.cn/4e1e71fe15cf45478753ea9452820329.png)


- 一种更好的方法来解决页面中文乱码问题,直接要求浏览器按照某种字符编码来显示中文
![在这里插入图片描述](https://img-blog.csdnimg.cn/14e0758fdc5845a9b6e78c6496bbeeb0.png)


`response.setContentType("text/html;charset=utf-8")`;让浏览器采用utf-8字符编码

- 重启tomcat服务器,访问`http://localhost:8080/WebDemo/chinese`
![在这里插入图片描述](https://img-blog.csdnimg.cn/444bdde3831445ea904f78df7f79a7e0.png)


- 当然也可以换种方式来解决
```xml
// 设置HttpServletResponse使用utf-8编码
response.setCharacterEncoding("utf-8"); 
// 通知浏览器使用utf-8解码
response.setHeader("Content-Type", "text/html;charset=utf-8"); 

六、HttpServletRequest对象

(一)获取请求行信息的相关方法

  • 目标:掌握使用HttpServletRequest接口中的方法获取请求行

1、相关方法

方法声明 功能描述
String getMethod( ) 该方法用于获取HTTP请求消息中的请求方式(如GET、POST等)
String getRequestURI( ) 该方法用于获取请求行中资源名称部分,即位于URL的主机和端口之后、参数部分之前的数据
String getQueryString( ) 该方法用于获取请求行中的参数部分,也就是资源路径后面问号(?)以后的所有内容
String getProtocol( ) 该方法用于获取请求行中的协议名和版本,例如HTTP/1.0或HTTP/1.1
String getContextPath( ) 该方法用于获取请求URL中属于Web应用程序的路径,这个路径以“/”开头,表示相对于整个Web站点的根目录,路径结尾不含“/”。如果请求URL属于Web站点的根目录,那么返回结果为空字符串(“”)
String getServletPath( ) 该方法用于获取Servlet的名称或Servlet所映射的路径
String getRemoteAddr( ) 该方法用于获取请求客户端的IP地址,其格式类似于“192.168.0.3”
String getRemoteHost( ) 该方法用于获取请求客户端的完整主机名,其格式类似于“pc1.itcast.cn”。需要注意的是,如果无法解析出客户机的完整主机名,该方法将会返回客户端的IP地址
int getRemotePort() 该方法用于获取请求客户端网络连接的端口号
String getLocalAddr() 该方法用于获取Web服务器上接收当前请求网络连接的IP地址
String getLocalName() 该方法用于获取Web服务器上接收当前网络连接IP所对应的主机名
int getLocalPort() 该方法用于获取Web服务器上接收当前网络连接的端口号
String getServerName() 该方法用于获取当前请求所指向的主机名,即HTTP请求消息中Host头字段所对应的主机名部分
int getServerPort() 该方法用于获取当前请求所连接的服务器端口号,即如果HTTP请求消息中Host头字段所对应的端口号部分
String getScheme() 该方法用于获取请求的协议名,例如http、https或ftp
StringBuffer getRequestURL() 该方法用于获取客户端发出请求时的完整URL,包括协议、服务器名、端口号、资源路径等信息,但不包括后面的查询参数部分。注意,getRequestURL()方法返回的结果是StringBuffer类型,而不是String类型,这样更便于对结果进行修改

2、案例演示

创建net.xyx.request包,在包里创建RequestLineServlet

package net.xyx.request;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 功能:输出请求行的相关信息
 * 作者:xyx
 * 日期:2023年03月13日
 */
@WebServlet(name = "RequestLineServlet", urlPatterns = "/request")
public class RequestLineServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 设置响应体内容类型
        response.setContentType("text/html;charset=utf-8");
        // 获取字符输出流
        PrintWriter out = response.getWriter();
        // 获取并输出请求行的相关信息
        out.println("getMethod: " + request.getMethod() + "<br />");
        out.println("getRequestURI: " + request.getRequestURI() + "<br />");
        out.println("getQueryString: " + request.getQueryString() + "<br />");
        out.println("getProtocol: " + request.getProtocol() + "<br />");
        out.println("getContextPath: " + request.getContextPath() + "<br />");
        out.println("getPathInfo: " + request.getPathInfo() + "<br />");
        out.println("getPathTranslated: " + request.getPathTranslated() + "<br />");
        out.println("getServletPath: " + request.getServletPath() + "<br />");
        out.println("getRemoteAddr: " + request.getRemoteAddr() + "<br />");
        out.println("getRemoteHost: " + request.getRemoteHost() + "<br />");
        out.println("getRemotePort: " + request.getRemotePort() + "<br />");
        out.println("getLocalAddr: " + request.getLocalAddr() + "<br />");
        out.println("getLocalName: " + request.getLocalName() + "<br />");
        out.println("getLocalPort: " + request.getLocalPort() + "<br />");
        out.println("getServerName: " + request.getServerName() + "<br />");
        out.println("getServerPort: " + request.getServerPort() + "<br />");
        out.println("getScheme: " + request.getScheme() + "<br />");
        out.println("getRequestURL: " + request.getRequestURL() + "<br />");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }
}
  • 重启tomcat服务器,访问http://localhost:8080/WebDemo/request
    ここに画像の説明を挿入します

  • getContextPath: /WebDemo + getServletPath: /request = getRequestURI: /WebDemo/request

  • getScheme: http + “:” + getServerName: localhost + “:” + getServerPort: 8080 + getRequestURI: /WebDemo/request = getRequestURL: - - -http://localhost:8080/WebDemo/request

  • URI: Uniform Resource Identifier 统一资源标识符

  • URL: Uniform Resource Locator 统一资源定位器
    演示请求字符串
    ここに画像の説明を挿入します

package net.xyx.request;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 功能:输出请求行的相关信息
 * 作者:xyx
 * 日期:2023年04月14日
 */
@WebServlet(name = "RequestLineServlet", urlPatterns = "/request")
public class RequestLineServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 设置响应体内容类型
        response.setContentType("text/html; charset=utf-8");
        // 获取字符输出流
        PrintWriter out = response.getWriter();
        // 获取并输出请求行的相关信息
        out.println("getMethod: " + request.getMethod() + "<br />");
        out.println("getRequestURI: " + request.getRequestURI() + "<br />");
        out.println("getQueryString: " + request.getQueryString() + "<br />");
        out.println("getProtocol: " + request.getProtocol() + "<br />");
        out.println("getContextPath: " + request.getContextPath() + "<br />");
        out.println("getPathInfo: " + request.getPathInfo() + "<br />");
        out.println("getPathTranslated: " + request.getPathTranslated() + "<br />");
        out.println("getServletPath: " + request.getServletPath() + "<br />");
        out.println("getRemoteAddr: " + request.getRemoteAddr() + "<br />");
        out.println("getRemoteHost: " + request.getRemoteHost() + "<br />");
        out.println("getRemotePort: " + request.getRemotePort() + "<br />");
        out.println("getLocalAddr: " + request.getLocalAddr() + "<br />");
        out.println("getLocalName: " + request.getLocalName() + "<br />");
        out.println("getLocalPort: " + request.getLocalPort() + "<br />");
        out.println("getServerName: " + request.getServerName() + "<br />");
        out.println("getServerPort: " + request.getServerPort() + "<br />");
        out.println("getScheme: " + request.getScheme() + "<br />");
        out.println("getRequestURL: " + request.getRequestURL() + "<br />");

        // 在控制台输出请求字符串的信息
        if (request.getQueryString() != null) {
            String strQuery = request.getQueryString();
            String[] queries = strQuery.split("&");
            for (String query : queries) {
                String[] fields = query.split("=");
                System.out.println(fields[0] + " : " + fields[1]);
            }
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }
}

  • 重启tomcat服务器,访问http://localhost:8080/WebDemo/request?username=howard&password=903213
    ここに画像の説明を挿入します

还可以将查询字符串继续按=进行拆分
ここに画像の説明を挿入します

(二)获取请求头的相关方法

  • 目标:掌握使用HttpServletRequest接口获取HTTP请求头字段的方法

1、相关方法

方法声明 功能描述
String getHeader(String name) 该方法用于获取一个指定头字段的值,如果请求消息中没有包含指定的头字段,getHeader()方法返回null;如果请求消息中包含有多个指定名称的头字段,getHeader()方法返回其中第一个头字段的值
Enumeration getHeaders(String name) 该方法返回一个Enumeration集合对象,该集合对象由请求消息中出现的某个指定名称的所有头字段值组成。在多数情况下,一个头字段名在请求消息中只出现一次,但有时候可能会出现多次
Enumeration getHeaderNames() 该方法用于获取一个包含所有请求头字段的Enumeration对象
int getIntHeader(String name) 该方法用于获取指定名称的头字段,并且将其值转为int类型。需要注意的是,如果指定名称的头字段不存在,返回值为-1;如果获取到的头字段的值不能转为int类型,将发生NumberFormatException异常
long getDateHeader(String name) 该方法用于获取指定头字段的值,并将其按GMT时间格式转换成一个代表日期/时间的长整数,这个长整数是自1970年1月1日0点0分0秒算起的以毫秒为单位的时间值
String getContentType() 该方法用于获取Content-Type头字段的值,结果为String类型
int getContentLength()
String getCharacterEncoding() 该方法用于返回请求消息的实体部分的字符集编码,通常是从Content-Type头字段中进行提取,结果为String类型

2、案例演示

  • 在net.xyx.request包里创建RequestHeadersServlet
package net.xyx.request;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;

/**
 * 功能:演示获取请求头的信息
 * 作者:xyx
 * 日期:2023年04月14日
 */
@WebServlet(name = "RequestHeaderServlet", urlPatterns = "/header")
public class RequestHeaderServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 设置响应体内容类型
        response.setContentType("text/html; charset=utf-8");
        // 获取字符输出流
        PrintWriter out = response.getWriter();
        // 获取请求头名枚举对象
        Enumeration<String> headerNames = request.getHeaderNames();
        // 遍历所有请求头,并通过getHeader()方法获取一个指定名称的头字段
        while (headerNames.hasMoreElements()) {
            // 获取头字段名称
            String headerName = headerNames.nextElement();
            // 输出头字段名称及其值
            out.println(headerName + " : " + request.getHeader(headerName) + "<br />");
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }
}

  • 重启tomcat服务器,访问http://localhost:8080/WebDemo/header
    ここに画像の説明を挿入します

  • 按F12键,通过开发者工具查看请求头信息
    ここに画像の説明を挿入します

(三)请求转发

  • 目标:掌握使用HttpServletRequest接口将请求转发

1、getRequestDispatcher()方法

  • Servlet之间可以相互跳转,利用Servlet的跳转可以很容易地把一项任务按模块分开,例如,使用一个Servlet实现用户登录,然后跳转到另外一个Servlet实现用户资料修改。Servlet的跳转要通过RequestDispatcher接口的实例对象实现。HttpServletRequest接口提供了getRequestDispatcher()方法用于获取RequestDispatcher对象,getRequestDispatcher()方法的具体格式: RequestDispatcher getRequestDispatcher(String path)
  • getRequestDispatcher() メソッドは、パスで指定されたリソースをカプセル化する RequestDispatcher オブジェクトを返します。このうち、パラメータのパスは「/」で始まる必要があり、現在の Web アプリケーションのルート ディレクトリを表すために使用されます。 WEB-INF ディレクトリの内容はRequestDispatcher オブジェクトからも参照できることに注意してください。したがって、getRequestDispatcher(String path) メソッドに渡されるリソースは、WEB-INF ディレクトリ内のファイルにすることができます。

2. forward() メソッド

  • オブジェクトを取得RequestDispatcherした後、現在の Web リソースがリクエストを処理したくない場合、RequestDispatcher インターフェイスは forward() メソッドを提供します。リクエストは他の Web リソースに渡されて情報を処理し、クライアントに応答します。この方法はリクエスト転送と呼ばれます。 forward() メソッドの特定の形式:forward(ServletRequest request,ServletResponse response)
  • forward() メソッドは、 1 つの Servlet から別の Web リソースにリクエストを渡すために使用されます。 Servlet では、リクエストに対して予備処理を実行し、forward() メソッドを呼び出すことで、リクエストを応答のために他のリソースに渡すことができます。このメソッドは、応答がクライアントに送信される前に呼び出す必要があることに注意してください。そうしないと、例外がスローされます。 ブラウザが Servlet1 にアクセスすると、 メソッドを通じてリクエストを他の Web リソースに転送できます。他の Web リソースがリクエストを処理した後、応答結果が直接返されます。ブラウザに戻りました。 IllegalStateException
    forward()

3. 症例デモンストレーションリクエストの転送

net.xyx.request パッケージにクラスを作成RequestForwardServletし、request オブジェクトにデータを保存して、別の < a i=3>処理するServlet

package net.xyx.request;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 功能:演示请求转发
 * 作者:xyx
 * 日期:2023年03月13日
 */
@WebServlet(name = "RequestForwardServlet", urlPatterns = "/forward")
public class RequestForwardServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 设置响应体内容类型
        response.setContentType("text/html;charset=utf-8");
        // 设置请求对象属性
        request.setAttribute("message", "欢迎访问泸州职业技术学院~");
        // 获取请求派发器对象(参数是请求转发的Servlet的url)
        RequestDispatcher dispatcher = request.getRequestDispatcher("/result");
        // 请求转发给url为`/result`的Servlet
        dispatcher.forward(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }
}

net.xyx.request パッケージに作成ResultServlet クラス。 に格納されている RequestForwardServlet データを取得するために使用されます。オブジェクトと出力request

package net.xyx.request;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 功能:处理转发的请求
 * 作者:xyx
 * 日期:2023年03月13日
 */
@WebServlet(name = "ResultServlet", urlPatterns = "/result")
public class ResultServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 设置响应体内容类型
        response.setContentType("text/html;charset=utf-8");
        // 获取字符输出流
        PrintWriter out = response.getWriter();
        // 获取请求转发保存在request对象里的数据
        String message = (String) request.getAttribute("message");
        // 输出获取的信息
        if (message != null) {
            out.println("转发来的消息:" + message);
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }
}

対応図

Tomcat サーバーを再起動し、http://localhost:8080/WebDemo/forward にアクセスします。

注: RequestForwardServlet のリクエスト パスはアドレス バーに表示されたままですが、ブラウザには ResultServlet に出力される内容が表示されます。これは、リクエストの転送がサーバ内で行われる動作であるためで、RequestForwardServlet から ResultServlet までがリクエストであり、リクエスト内では request 属性をデータ共有(同一リクエスト転送)に使用することができます。

(4) リクエスト パラメータを取得する
目的: HttpServletRequest インターフェースを使用してリクエスト パラメータを取得することをマスターする
1. 関連メソッド< a i=3 > メソッド宣言関数の説明 String getParameter(String name) このメソッドは、指定された名前のパラメータ値を取得するために使用されます。リクエスト メッセージに指定された名前のパラメータが含まれていない場合は、 、getParameter() メソッドは null を返します。指定された名前のパラメータが存在するが値が設定されていない場合は、空の文字列が返されます。リクエスト メッセージに指定された名前のパラメータが複数含まれている場合、getParameter() メソッドは最初のパラメータを返します。表示されるパラメータ値 String[] getParameterValues(String name) このメソッドは、String 型の配列を返すために使用されます。HTTP リクエスト メッセージ (通常は生成される) 内に同じ名前の複数のパラメータが存在する可能性があります。同じ名前の複数のフィールド要素を含むフォームによって).)、HTTP リクエスト メッセージ内の同じパラメータ名に対応するすべてのパラメータ値を取得したい場合は、 getParameterValues() メソッドを使用する必要があります< a i=6> Enumeration getParameterNames() このメソッドは、リクエスト メッセージ内のすべてのパラメータ名の Enumeration オブジェクトを含むリクエスト メッセージを返すために使用されます。これに基づいて、リクエスト メッセージ内のすべてのパラメータを調べることができます。 Map getParameterMap() このメソッドは、リクエスト メッセージ内のすべてのパラメータ名と値を取得するために使用されます。Map オブジェクトにロードして戻ります。 2. ケースのデモ 登録ページを作成します - register.html






用户注册 新規ユーザー登録
ユーザー名:
パスワード:
性別: 男女
興味: 映画を見たり、コードを書いたり、ゲームをしたり

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

  • net.xyx.request パッケージに RquestParamsServlet クラスを作成
package net.xyx.request;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 功能:获取请求参数
 * 作者:XYX
 * 日期:2023年04月14日
 */
@WebServlet(name = "RequestParamsServlet", urlPatterns = "/register")
public class RequestParamsServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {       
        // 设置响应体内容类型
        response.setContentType("text/html; charset=utf-8");
        // 获取字符输出流
        PrintWriter out = response.getWriter();
        // 获取注册表单提交的数据
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String gender = request.getParameter("gender");
        String[] interests = request.getParameterValues("interest");
        // 输出获取的表单数据
        out.println("姓名:" + username + "<br />");
        out.println("密码:" + password + "<br />");
        out.println("性别:" + gender + "<br />");
        out.print("兴趣:");
        for (int i = 0; i < interests.length; i++) {
            out.println(interests[i]);
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }
}

対応図

ここに画像の説明を挿入します

Tomcat サーバーを再起動し、http://localhost:8080/WebDemo/register.html にアクセスして、フォーム データを入力します
ここに画像の説明を挿入します

[登録]ボタンをクリックします
ここに画像の説明を挿入します

(5)リクエストパラメータの中国語文字化け問題を解決

  • 目標: 中国語の文字化けリクエストパラメータを解決する方法をマスターする

  • HttpServletRequest インターフェイスには、setCharacterEncoding() メソッドが提供されており、request オブジェクト

  • クラスを変更し、コード行を追加して、リクエスト オブジェクトの文字エンコーディングを設定しますResquestParamsServlet
    ここに画像の説明を挿入します

  • Tomcat サーバーを再起動し、http://localhost:8080/WebDemo/register.html にアクセスして、フォーム データを入力します
    ここに画像の説明を挿入します

  • [登録]ボタンをクリックすると、ページ上の中国語の文字化けはなくなります。
    画面録画デモ登録操作

(6) Request オブジェクトを介してデータを渡す

  • 目標: ServletRequest インターフェースを使用して属性を操作する方法をマスターする

1. Requestオブジェクトの属性を操作するメソッド

(1)setAttribute()方法
  • setAttribute() メソッドは、オブジェクトを name に関連付け、 ServletRequest オブジェクトに格納するために使用されます。その完全な宣言: public void setAttribute(String name,Object o);
    setAttribute()メソッドのパラメータ リストの最初のパラメータは String 型の名前を受け取り、2 番目のパラメータは Object 型のオブジェクトを受け取ります。指定された名前の属性がServletRequestオブジェクトにすでに存在する場合、setAttribute() メソッドは最初に元の属性を削除してから、新しい属性を追加することに注意してください。 。 setAttribute() メソッドに渡された属性値オブジェクトが null の場合、指定された名前の属性が削除されます。その効果は removeAttribute() メソッドと同じです。
(2)getAttribute()方法
  • getAttribute() メソッドは、ServletRequest オブジェクトから指定された名前の属性オブジェクトを返すために使用されます。その完全な宣言: public Object getAttribute(String name);
(3)removeAttribute()方法
  • removeAttribute() メソッドは、指定された名前の属性を ServletRequest オブジェクトから削除するために使用されます。その完全な宣言: public void removeAttribute(String name);
(4) getAttributeNames()メソッド
  • getAttributeNames() メソッドは、 ServletRequest オブジェクト内のすべての属性名を含む Enumeration オブジェクトを返すために使用されます。これに基づいて、 < a i=3>オブジェクト内のすべての属性がスキャンされます。完全なステートメント: ; 同じリクエストに属するデータのみが オブジェクトを介してデータを渡すことができることに注意してください。 。 ServletRequestpublic Enumeration getAttributeNames()
    ServletRequest

2. Request オブジェクトを介してデータを転送するケースのデモンストレーション

net.xyx.request パッケージにクラスを作成RquestServlet01します

package net.xyx.request;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 功能:设置请求对象属性,请求转发
 * 作者:xyx
 * 日期:2023年04月14日
 */
@WebServlet(name = "RequestServlet01", urlPatterns = "/request01")
public class RequestServlet01 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        // 设置响应体内容类型
        response.setContentType("text/html; charset=utf-8");
        // 设置请求对象属性
        request.setAttribute("id", "20210201");
        request.setAttribute("name", "陈燕文");
        request.setAttribute("gender", "女");
        request.setAttribute("age", "18");
        request.setAttribute("major", "软件技术专业");
        request.setAttribute("class", "2021级软件2班");
        request.setAttribute("phone", "15890903456");
        // 获取请求派发器对象(参数是请求转发的Servlet的url)
        RequestDispatcher dispatcher = request.getRequestDispatcher("/request02");
        // 请求转发给url为`/request02`的Servlet
        dispatcher.forward(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        doPost(request, response);
    }
}

  • net.xyx.request包里创建RquestServlet02
package net.xyx.request;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;

/**
 * 功能:获取请求转发的数据
 * 作者:xyx
 * 日期:2023年04月14日
 */
@WebServlet(name = "RequestServlet02", urlPatterns = "/request02")
public class RequestServlet02 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 设置响应体内容类型
        response.setContentType("text/html; charset=utf-8");
        // 获取字符输出流
        PrintWriter out = response.getWriter();
        // 获取请求对象属性名枚举对象
        Enumeration<String> attributes = request.getAttributeNames();
        // 获取请求转发保存在request对象里的数据并输出
        while (attributes.hasMoreElements()) {
            // 获取属性名
            String attribute = attributes.nextElement();
            // 输出属性名及其值
            out.println(attribute + " : " + request.getAttribute(attribute) + "<br />");
        }
        // 删除请求对象的属性
        while (attributes.hasMoreElements()) {
            // 获取属性名
            String attribute = attributes.nextElement();
            // 删除属性
            request.removeAttribute(attribute);
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }
}
  • サーバーを起動してアクセスするhttp://localhost:8080/WebDemo/request01
    ここに画像の説明を挿入します

  • RequestServlet02 を変更して学生情報のみを表示する

package net.huawei.request;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 功能:获取请求转发的数据
 * 作者:xyx
 * 日期:2023年04月14日
 */
@WebServlet(name = "RequestServlet02", urlPatterns = "/request02")
public class RequestServlet02 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 设置响应体内容类型
        response.setContentType("text/html; charset=utf-8");
        // 获取字符输出流
        PrintWriter out = response.getWriter();
        // 获取请求转发保存在request对象里的数据并输出
        out.println("学号:" + request.getAttribute("id") + "<br />");
        out.println("姓名:" + request.getAttribute("name") + "<br />");
        out.println("性别:" + request.getAttribute("gender") + "<br />");
        out.println("年龄:" + request.getAttribute("age") + "<br />");
        out.println("专业:" + request.getAttribute("major") + "<br />");
        out.println("班级:" + request.getAttribute("class") + "<br />");
        out.println("手机:" + request.getAttribute("phone") + "<br />");
        // 删除请求对象的属性
        request.removeAttribute("id");
        request.removeAttribute("name");
        request.removeAttribute("gender");
        request.removeAttribute("age");
        request.removeAttribute("major");
        request.removeAttribute("class");
        request.removeAttribute("phone");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }
}
  • サーバーを起動してアクセスするhttp://localhost:8080/WebDemo/request01

おすすめ

転載: blog.csdn.net/m0_63887380/article/details/130422991