JavaWeb〜Servlet〜の基本的な使用法、スマートTomcatプラグイン、サーブレットの動作原理の深い理解、Tomcatの初期化、およびリクエスト処理のコアロジック

サーブレットの基本的な使用法

ステップ
1.IDEAがmavenプロジェクトを作成します
2.中央ウェアハウスに依存関係を導入します〜3
。ディレクトリ構造を作成しますwebapp / WEB-INF / web.xml
4.コードを記述します
1)継承するクラスを作成しますHttpServlet
2)HttpServlet doGet/doPostを書き直しますメソッド
3)メソッド内のリクエストに従ってレスポンスを計算し、レスポンスオブジェクトに直接「helloworld」を構築します
。4)クラスにアノテーション@WebServletを追加して、クラスを特定のHTTPリクエストのパスに関連付けます
〜5 。パッケージ化、maven
を使用してパッケージングタグを使用してパッケージ化タイプを変更し、ビルドタグfinalNameタグがパッケージ化された名前を指定します
6.デプロイし、warパッケージをTomcatのwebappsディレクトリにコピーすると、
Tomcatは自動的にwarパッケージを解凍して同じ名前のディレクトリ
7.http
:// serverのip:8080 / ContextPath/[WebServletアノテーションに記述されているパス]を確認します

スマートTomcatプラグイン

プラグインplugin
コンピュータには多くのプログラムがあり、すべて「プラグインシステム」に基づいています。

初期の有名なプラグインシステムのプログラムエディタのVim
とEmacsには
、有名なEclipseを含むいくつかの追加のプラグインが装備されています。
現在、Eclipseは単なる「プラットフォーム」です。さまざまなプラグインと照合した後、 Java開発ツール/C++開発ツールツールなどになることができます。

サーブレットプログラムの展開をより適切かつ迅速に完了するために、完了することができるプラグインがあります。つまり、Smart Tomcat
スマートTomcatをインストールする
ここに画像の説明を挿入
には、ポップアップウィンドウで[プラグイン(プラグイン)]をクリックしてから、スマートTomcatをクリックし、[インストール]をクリックして、ダウンロードしてインストールします。
ここに画像の説明を挿入
アイデアに次のログが表示されている場合は、プラグインが正常に実行されていることを意味します。
ここに画像の説明を挿入

Smart Tomcatプラグインの動作原理は、一時的に別のディレクトリを作成し、現在のコードを一時的なコピーにコピーして、Tomcatを実行させることです。これにより、warパッケージが元のwebappsディレクトリに表示されなくなります。

一般的な問題

プログラムをTomcatにデプロイした後、アクセスすると次の状況が発生する
可能性があります。1. 404の考えられる原因
:パスUR1が正しく入力されていません。
2. 405の考えられる理由
:リクエストメソッドがコード内のオーバーライドされたメソッドと一致しません。
3. 500の
考えられる原因:内部サーバーコードが異常に実行されています。
4.空白のページが表示
されます。5。Webサイトにアクセスできません。

サーブレットの動作原理の深い理解

WebサーバーはHTTPリクエストを受信すると、最初にリクエストのコンテンツを決定します静态。Webページデータの場合、Webサーバーはそれを自動的に処理します。动态データコンテンツの場合、WebサーバーはリクエストをTomcat(に転送します。つまり、サーブレット)、次にサーブレットが要求を処理するための対応するインスタンスが検出され、結果がWebサーバーに返され、Webサーバーがそれをクライアントに返します。

同じサーブレットの場合、Tomcatは最初にHTTPリクエストを受信したときにサーブレットインスタンスを作成し、次にスレッドを作成します。2回目にHTTPリクエストを受信したときに、同じサーブレットインスタンスを再度作成することはありません。代わりに、クライアントの要求を処理するために2番目のスレッドが開始されます。

したがって、サーブレットは実行されてい多线程的环境ます。マルチスレッドは、Webアプリケーションの実行効率を向上させるだけでなく、Webサーバーのシステム負荷を軽減することもできます。
ここに画像の説明を挿入

クライアントとサーバー間の詳細な対話プロセス:

ここに画像の説明を挿入
リクエスト処理のプロセス:
ユーザーがブラウザに入力すると、ブラウザURlはHTTPリクエストメッセージを作成し、メッセージはネットワークプロトコルスタックによって順番にカプセル化され、トランスポートレイヤーを通過し、ヘッダーがTCP設定されて通過します。ネットワーク層、およびセットヘッダーipは、データリンク層を介して、フレームヘッダーとイーサネットデータフレームのフレーム端で覆われ、物理層を介して0101に変換され光电信号、ネットワークを介して転送および送信され、最後にサーバーの物理層に到達し、次に物理層を通過します。、光電信号をに変換し数字信号、データリンク層に到達し、イーサネットデータフレームを解析し、内部のキャリアコアを取り出し、ネットワーク層を通過します。 、ipプロトコルを介して解析し、キャリアコアを取り出し、トランスポート層でTCPプロトコルを介して解析します。次に、アプリケーション層でHTTP要求メッセージを取得し、Tomcat要求を解析してHttpServletRequestオブジェクトを生成します。次にContextPath、オブジェクト内の情報に基づいて、どのWebアプリケーションに渡すか、次にServletPathどのクラスに渡すかがレポートに従って決定され、次にレポートに従って決定されます。このペーパーのメソッドは、実行するメソッドを決定します。最後に特定のコードを実行します。

擬似コードは、Tomcatのコアロジックを記述します

擬似コード:大まかに特定のロジックを表し、構文は必ずしも厳密ではありません。

Tomcatの初期化プロセス


//假设Tomcat就是一个类
class Tomcat {
    
    

 // 用来存储所有的 Servlet 对象
 //首先会用一个List来记录所有的Servlet实例,我们自己写类时都会重写doGet或者doPost等方法,这些方法的调用就是依靠这些实例,这里用数组来储存这些Servlet实例
 private List<Servlet> instanceList = new ArrayList<>();
 
  //Tomcat启动时就会调用这个start方法
 public void start() {
    
    
       // 根据约定,读取 WEB-INF/web.xml 配置文件;
        // 并解析被 @WebServlet 注解修饰的类
       
        // 假定这个数组里就包含了我们解析到的所有被 @WebServlet 注解修饰的类. 
        //数组来储存所有的Servlet类对象,这些类对象就是webapps目录下的配置文件产生,也有根据我们自己写的类所生成的对象。
        Class<Servlet>[] allServletClasses = ...;
        //以上就是类的加载 的过程

  
     //加载完成后,就要对所有的类进行实例化,这里是通过反射来完成的。
        
        // 这里要做的的是实例化出所有的 Servlet 对象出来;
        for (Class<Servlet> cls : allServletClasses) {
    
    
            // 这里是利用 java 中的反射特性做的
           // 实际上还得涉及一个类的加载问题,因为我们的类字节码文件,是按照约定的
            // 方式(全部在 WEB-INF/classes 文件夹下)存放的,所以 tomcat 内部是
            // 实现了一个自定义的类加载器(ClassLoader)用来负责这部分工作。
            
            Servlet ins = cls.newInstance();
            instanceList.add(ins);
       }
        

        // 调用每个 Servlet 对象的 init() 方法,这个方法在对象的生命中只会被调用这一次;
        for (Servlet ins : instanceList) {
    
    
            ins.init();
       }
        
        // 利用我们之前学过的知识,启动一个 HTTP 服务器
        // 并用线程池的方式分别处理每一个 Request
    //创建Socket绑定端口号,开始启动服务器
        ServerSocket serverSocket = new ServerSocket(8080);
        // 实际上 tomcat 不是用的固定线程池,这里只是为了说明情况
        ExecuteService pool = Executors.newFixedThreadPool(100);
     
        
        //循环调用accept方法,每次accept返回的结果都会放到线程池里面,用doHttpRequest处理请求。
        while (true) {
    
    
            Socket socket = ServerSocket.accept();
            // 每个请求都是用一个线程独立支持,这里体现了我们 Servlet 是运行在多线程环境下的
            pool.execute(new Runnable() {
    
    
               doHttpRequest(socket); 
           });
       }

        
        //Servlet开始销毁,调用destroy方法
        // 调用每个 Servlet 对象的 destroy() 方法,这个方法在对象的生命中只会被调用这一次;
        for (Servlet ins : instanceList) {
    
    
            ins.destroy();
       }
   }
    
    public static void main(String[] args) {
    
    
        new Tomcat().start();
   }
}

これは単なる擬似コードであり、いくつかの一般的なプロセスです。実際のTomcat実行プロセスは、このロジックよりも少し複雑になります。

要約:

  • Tomcatにはmainメソッドが組み込まれています。Tomcatを起動すると、Tomcatのmainメソッドから実行が開始されます。
  • 最初に、クラスがロードされます。ロードプロセス中に、@WebServlet注釈付きのクラス、つまり自分で作成したクラスが取得されます。これらのクラスは一元管理されます。
  • 次に、クラスをインスタンス化し、リフレクションによって作成します。
  • インスタンスが作成された後、その中のメソッドが初期化のために呼び出さinitれます。このメソッドは、HttpServletに付属しているメソッドです。
  • 次に、リクエストaccpetを処理するためにスレッドにループされます。doHttpReuqest
  • 最後に、インスタンスが破棄され、破棄される前に、dextoryメソッドが呼び出されてさらに終了します。

サーブレット自体はマルチスレッド環境で実行されています。

Tomcatがリクエストを処理します

class Tomcat {
    
    
    void doHttpRequest(Socket socket) {
    
    
        // 参照我们之前学习的 HTTP 服务器类似的原理,进行 HTTP 协议的请求解析,和响应构建
        HttpServletRequest req = HttpServletRequest.parse(socket);
        HttpServletRequest resp = HttpServletRequest.build(socket);
        
        // 判断 URL 对应的文件是否可以直接在我们的根路径上找到对应的文件,如果找到,就是静态
内容
        // 直接使用我们学习过的 IO 进行内容输出
        if (file.exists()) {
    
    
            // 返回静态内容
            return;
       }
        
        // 走到这里的逻辑都是动态内容了
        
        // 根据我们在配置中说的,按照 URL -> servlet-name -> Servlet 对象的链条
        // 最终找到要处理本次请求的 Servlet 对象
        Servlet ins = findInstance(req.getURL());
        
        // 调用 Servlet 对象的 service 方法
        // 这里就会最终调用到我们自己写的 HttpServlet 的子类里的方法了
        try {
    
    
       ins.service(req, resp); 
       } catch (Exception e) {
    
    
            // 返回 500 页面,表示服务器内部错误
       }
   }
}

要約:

  • TomcatはソケットからHttpリクエストを読み取ります。このとき、読み取りリクエストは文字列でありHttpServletRequest、HTTPプロトコルの形式に従ってオブジェクトに解析されます。
  • Tomcatは、URLのパスにpath基づいて、現在の要求が動的であるか静的であるかを判別します。静的な場合は、対応するファイルコンテンツをローカルで直接検索し、Socketを介して返します。動的な場合は、サーブレット関連のロジックを実行します。
  • 次に、URLの合計ContextPathに基づいて、呼び出すサーブレットインスタンスのメソッドを決定します。ServletPathservice
  • serviceメソッドを呼び出して、リクエストの処理を開始します。

serviceメソッドは、私たちが定義するクラスであり、doGetやdoPostなどのメソッドがオーバーライドされます。
ロジックは次のとおりです。

class Servlet {
    
    
    public void service(HttpServletRequest req, HttpServletResponse resp) {
    
    
        String method = req.getMethod();
        if (method.equals("GET")) {
    
    
            doGet(req, resp);
       } else if (method.equals("POST")) {
    
    
            doPost(req, resp);
       } else if (method.equals("PUT")) {
    
    
            doPut(req, resp);
       } else if (method.equals("DELETE")) {
    
    
            doDelete(req, resp);
       } 
       ......
   }
}

ここでdoXXXメソッドが呼び出されると
多态メカニズムがされます。作成したクラスはすべてHttpServletクラスを継承し、HttpServletクラスはサーブレットを継承するため、作成するクラスはサーブレットのサブクラスです。
これは、ポリモーフィックな継承関係を満たします。
Tomcatが起動すると、Tomcatはアノテーションの説明に従って作成したクラスのインスタンスを作成し、集中管理のためにサーブレット配列に配置します。URLを介して配列からインスタンスを取り出すと、サーブレットinsなどの親クラス参照を介してインスタンスが取得されます。次にins.doGet、メソッドがメソッドによって呼び出されたとき。
これは父类引用指向子类对象、この。

おすすめ

転載: blog.csdn.net/Merciful_Lion/article/details/123561377