JavaWebのコアHttpServletRequestおよびHttpServletResponse

序文

Javaが誕生してから20年以上経ちますが、幸運にも開発の初期段階でこの言語を固めることができました。Javaエコシステムがますます活発になり、Javaの設計アイデアが時代によってますます認識され、Java開発者が増えるにつれて、Javaエコシステムは企業のように成長し、新鮮な血を引き続けると私は信じています。 。そして、30年、50年、さらには100年までの継続的な革新と開発。
Javaは、テレビ、冷蔵庫、洗濯機などのさまざまなハードウェアデバイスでアプリケーションを作成するために生まれました。そのため、JVMはさまざまな基盤システムをシールドするように設計されました。しかし、期待どおりに開発されなかったため、誤って使用されました。 Javaは初期にはWeb用に作成されていなかったため、誤ってインターネットとの深い接続、つまりJava Webのタイトルを偽造した人は、Javaは学校であり、Webはその開発の弟子にすぎませんが、これはウェブの弟子。、ジャバの武道を繁栄の時代に押し上げる。
Javaの成長は2000年から2010年の間に現れました。世界でのインターネット技術の継続的な発展に伴い、サーブレットの誕生はインターネットの発展に対応するJavaの産物であり、Javaを後押しした画期的な変化でもあります。インターネット開発技術に。
では、サーブレットとは何ですか?

インターネット

サーブレットを理解する前に、ネットワークを理解する必要があります。前述のように、サーブレットはインターネットの誕生に対応する製品であるため、最初にインターネット、次にサーブレットがあります。
ネットワークの概念は前世紀に生まれました。世界の産業の継続的な成長に伴い、CPU、メモリなどのコンピュータのさまざまなコンポーネントが継続的にアップグレードされ、より強力なコンピュータ機能とより高度なコンピューティングが実現しました。効率とスピード。人々はコンピューターを接続するというアイデアを提唱していますが、どのように接続しますか?
あるコンピュータから別のコンピュータへの通信では、人々はそれらを上から下にISO 7層モデルに分割し、それがTCP / IPネットワークモデルのその後の開発につながりました。しかし、このモデルは単なるネットワーク通信の骨格であり、骨格だけに肉体と血がなく、完全な体とは言えません。
その結果、各レイヤー間で多くの合意、つまり合意が生まれました。ファイルの伝達に使用される形式、メールの伝達に使用される形式など。その中には、Webページの相互作用に使用される現在有名なHTTPプロトコルがあります。

HTTP

Httpは、テキストを転送できるだけでなく、写真、ビデオ、その他のメディアも転送できるため、ハイパーテキスト転送プロトコルです。Baiduには特定の概念があるため、ここでは繰り返しません。
ここで説明したいのは、HTTPとサーブレットの接続です。
まず、コンピューターがHTTPに基づいてコンピューターと通信する方法を見てみましょう。
ここに画像の説明を挿入
上の画像の濃い英語は非常によく知られています。Webページを開いてF12を押すと、メッセージがポップアップします。F12は、リクエストヘッダー、リクエスト本文、レスポンス本文などを含むHTTPメッセージです。
そしてSerlet?
Javaはプログラミング言語であり、サーブレットは当然情報を書き込むためのツールであり、HttpServletは当然Http情報を書き込むためのツールです。
これが私が上で述べたことであり、サーブレットがインターネットに対応する製品である理由です。

この記事の中核は、HttpServletRequestとHttpServletResponseです。
Javaプログラマーとして、Java Webをプレイしたい場合は、Webのコアサーブレットを理解する必要があります。したがって、HttpServletはサーブレットのコアです。

HttpServletは、現在のインターネット時代におけるJavaの開発と成長の中核です。

前述のように、HttpServletはHttp情報を書き込むためのツールです。Httpのコンポーネントを知っている限り、HttpServletの設計原則を自然に理解できます。

Http構成

Httpはステートレス、コネクションレスの要求/応答プロトコルであるため、要求と応答
要求の2つの部分に分けることができます
要求には要求ヘッダーと要求本文
が含まれます要求ヘッダーには要求行、要求属性、およびエンドライン。
リクエストラインリクエストメソッド、URL、プロトコルバージョンの
レスポンスも含まれます
レスポンスにはレスポンスヘッダーとレスポンスボディ
が含まれますレスポンスヘッダーにはレスポンスライン、レスポンス属性、エンド
ラインが含まれますレスポンスラインにはレスポンスステータスが含まれますコード、プロトコルバージョンなど。

具体的な関係構造図は次のとおりです。
ここに画像の説明を挿入

最初の部分を見てください:

(1)HTTPリクエスト

(1)リクエストメソッド
リクエストヘッダーにはリクエストラインが含まれ、リクエストラインにはリクエストメソッドが含まれます。
一般的なリクエストメソッドは、GET / POST / PUT / DELETEなどです。最も一般的に使用されるメソッドはGETとPOSTです。
GETメソッドの場合、リクエストパラメータはURLでスプライスされるため、リクエストの本文はありません。そのため、長さが制限され、露出がより明確になります。
POSTメソッドの場合、パラメーターがリクエストボディに格納されるため、リクエストボディが必要です。これにより、長さが制限されず、公開が比較的安全になります。
(2)リクエスト属性
一般的なリクエスト属性は次のとおりです。

Connection: keep-alive                                  # 维护客户端和服务端的连接关系 
Content-Length: 68                                      # 描述HTTP消息实体的传输长度
Accept: application/json, text/javascript, */*; q=0.01          #发送端(客户端)希望接受的数据类型、q 是权重系数,范围 0 =< q <= 1,q 值越大,请求越倾向于获得其“;”之前的类型表示的内容
Origin: http://apptest.zhidianlife.com:8007            # 浏览器在referrer字段中只显示源网站的源地址(即协议、域名、端口),而不包括完整的路径  
Authorization: c81e7286507f4aa4b6179f4c381b4c64          # 请求所需的认证信息
User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64)      AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36          # 客户端版本号的名字
Content-Type: application/json                     # 请求实体,文档类型
Referer: http://apptest.zhidianlife.com:8007/procurement/order?_t=756512&_winid=w9290         #  从来于哪里
Accept-Encoding: gzip, deflate                        # 客户端接收编码类型,一些网络压缩格式: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9                      # 客户端接收的语言类型 、中文

(3)エンドマーカー
上の図で最も見落とされがちなのは、最後のCRLF、つまりエンドマークです。一般に、JavaでHttpプロトコルをシミュレートする場合、\ r \ n識別子を最後に追加する必要があります。これは、このユニット情報の最後を意味します。

(2)、HTTP応答

(1)応答ステータスコード
応答ヘッダーには、HTTPプロトコルバージョン、応答ステータスコードなどが含まれます。
応答ステータスコードには5つのカテゴリがあり、ステータスコードは1から始まり、2から始まり、3から始まり、4から始まり、5から始まります。1XX
...
2XX ...
3XX ...
4XX ...
5XX ...
(2)応答本文
応答本文はWebページのソースコードであり、クライアントブラウザはWebページのソースコードを解析してレンダリングします動的操作ページに移動します。
(3)終了マーカー
終了マーカーは、上記の終了識別子に準拠しています。

HttpServlet

HttpServletはHttp用に開発されています。Httpの構成を理解すると、そのメカニズムを大まかに理解できます。特定の状況については、ソースコードで詳細に説明されており、HttpServletの機能を確認できます。

public abstract class HttpServlet extends GenericServlet {
# 这一部分定义了各种请求方法的标识符
private static final long serialVersionUID = 1L;
private static final String METHOD_DELETE = "DELETE";
private static final String METHOD_HEAD = "HEAD";
private static final String METHOD_GET = "GET";
...

# 这一部分定义了各种请求方法的具体实现 	
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
	....省略
}
protected void doHead(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
	....省略
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
	....省略
}
protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
	....省略
}
...

#最重要的service方法
 protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String method = req.getMethod();
    long lastModified;
    
    # 如果是get请求,则转到get方法中..下同
    if (method.equals("GET")) {
        lastModified = this.getLastModified(req);
        if (lastModified == -1L) {
            this.doGet(req, resp);
        } else {
            long ifModifiedSince;
            try {
                ifModifiedSince = req.getDateHeader("If-Modified-Since");
            } catch (IllegalArgumentException var9) {
                ifModifiedSince = -1L;
            }

            if (ifModifiedSince < lastModified / 1000L * 1000L) {
                this.maybeSetLastModified(resp, lastModified);
                this.doGet(req, resp);
            } else {
                resp.setStatus(304);
            }
        }
    } else if (method.equals("HEAD")) {
        lastModified = this.getLastModified(req);
        this.maybeSetLastModified(resp, lastModified);
        this.doHead(req, resp);
    } else if (method.equals("POST")) {
        this.doPost(req, resp);
    } 
    ....
}
}

Java Webの始まりは、サーブレットをカスタマイズし、HttpServletを継承することによってサービスメソッドを実装することです。渡されたカスタムサーブレットのサービスメソッドは、上位層から呼び出されたときに呼び出されます。
ここには2つの質問があります。
(1)カスタムサーブレットがServiceメソッドを正常に呼び出す前にHttpServletを継承する必要があるかどうか。
(2)カスタムサーブレットがサーブレットインターフェースを直接実装して、アクセスを要求する目的を達成できるかどうか。
推測:
上位層はHttpServletのサービスメソッドを呼び出します。HttpServletまたはそのサブクラスを渡す限り、渡されたオブジェクトのサービスメソッドを正常に呼び出すことができます。

上层调用方法猜想:
?   ?   ?method(HttpServlet  httpServlet){
	httpServlet.service(httpServletRequest , httpServletResponse);
}

実験と検証を通じて
、カスタマイズされたMyServletがサーブレットを実装ている限り、カスタマイズされたMyServletのサービスメソッドを正常に呼び出すことができることがわかりました。
これは、上位層がHttpServletのサービスメソッドではなく、インターフェイスサーブレットのサービスメソッドを呼び出すことを示しています。
サーブレットとHttpServletの違いは何ですか?
ここに画像の説明を挿入
HttpServletはサーブレットのサブクラスです。サーブレットに加えて、より多くの関数を実装し、HTTPプロトコルのさまざまな要求メソッドと処理メソッドをカスタマイズします。サーブレット関数を継承し、HTTP関連の処理メソッドを拡張します。これは抽象クラスですが、抽象メソッドはありません。これは、サブクラスがそのメソッドのいずれかを実装することが必須ではないことを示しています。
上記のHttpServletのサービスソースコードでわかるように、サービスはルーティングと転送を行い、さまざまなリクエストメソッドに従ってさまざまな特定の実装メソッドに転送されます。上位層は、呼び出されたときに、
HttpServletRequestとHttpServletResponseの2つのオブジェクトをサービスメソッドに挿入します
(1)それらは何であり、どこから来たのですか?
(2)彼らの内部の方法と彼らができることは何ですか。

上位レベルはどこですか?

サーブレットは上位層によって制御され、サービスメソッドも上位層によって呼び出されます。では、上位レベルはどこにあり、それは何ですか?
ここでWebコンテナを紹介しますが、Webコンテナとは何ですか?文字通り、それはWebプログラムを保持するコンテナであり、Webプログラムはサーブレットとして明確に理解できます。したがって、WebコンテナはSerlvetのコンテナとしても理解できます。
ここに画像の説明を挿入
Webコンテナはアプリケーションの総称であり、特にTomcatやJBossなどのミドルウェアが含まれます。

HttpServletRequest

Webコンテナとこのオブジェクトの関係は何ですか?
HttpServletRequestはリクエストオブジェクトです。Webコンテナは、受信したHTTP情報を解析してHttpServletRequestオブジェクトを生成する役割を果たします。したがって、このオブジェクトは実際にはHTTPプロトコルリクエスト情報のカプセル化です。
リクエストヘッダー、リクエスト本文パラメータ、プロトコルバージョン、リクエストアドレス、タイムスタンプ、Cookie、セッションなどのさまざまなパラメータが含まれています。
具体的には、呼び出しチェーンを追跡できます。HttpServletRequestオブジェクト情報はトップレベルのインターフェイスServletRequestから取得され、このインターフェイスから呼び出すことができる情報はカプセル化された情報です。

public interface ServletRequest {

Object getAttribute(String var1);  // 某个属性

Enumeration<String> getAttributeNames(); // 属性集合

String getCharacterEncoding(); // 编码方式

void setCharacterEncoding(String var1) throws UnsupportedEncodingException;

int getContentLength();  // 请求体长度

long getContentLengthLong();

String getContentType(); // 请求体内容形式

ServletInputStream getInputStream() throws IOException;

String getParameter(String var1);  // 请求体参数

Enumeration<String> getParameterNames(); // 请求体参数集合

String[] getParameterValues(String var1); // 请求体中的value值

Map<String, String[]> getParameterMap();  // 请求体中的value值集合

String getProtocol(); // 协议

String getScheme();

String getServerName(); 

int getServerPort(); // 端口

BufferedReader getReader() throws IOException;

String getRemoteAddr(); 

String getRemoteHost(); // 请求主机

void setAttribute(String var1, Object var2);

void removeAttribute(String var1);

Locale getLocale();

Enumeration<Locale> getLocales();

boolean isSecure();

RequestDispatcher getRequestDispatcher(String var1);

/** @deprecated */
@Deprecated
String getRealPath(String var1);

int getRemotePort();

String getLocalName();

String getLocalAddr();

int getLocalPort();

ServletContext getServletContext();

AsyncContext startAsync() throws IllegalStateException;

AsyncContext startAsync(ServletRequest var1, ServletResponse var2) throws IllegalStateException;

boolean isAsyncStarted();

boolean isAsyncSupported();

AsyncContext getAsyncContext();

DispatcherType getDispatcherType();
}

HttpServletResponse

このオブジェクトは同じで、HTTP応答情報のカプセル化です。
具体的には、ServletResponseオブジェクトまでたどることができます。

public interface ServletResponse {
String getCharacterEncoding();

String getContentType();

ServletOutputStream getOutputStream() throws IOException;

PrintWriter getWriter() throws IOException;

void setCharacterEncoding(String var1);  // 设置编码方式

void setContentLength(int var1);

void setContentLengthLong(long var1);

void setContentType(String var1);

void setBufferSize(int var1);

int getBufferSize();

void flushBuffer() throws IOException;

void resetBuffer();

boolean isCommitted();

void reset();

void setLocale(Locale var1);

Locale getLocale();
}

インタラクティブプロセス全体

上記からわかるように、Webページは応答プロセスを要求します。
ここに画像の説明を挿入

クライアントは通常、ブラウザを使用してアクセスします。ユーザーがブラウザを使用してサーバーにメッセージを送信すると、

  1. ブラウザはクライアントのリクエストをHTTPプロトコルの形式でサーバーに送信します
  2. WebコンテナはHTTPプロトコルをHttpServletRequestオブジェクトとHttpServletResponseオブジェクトにカプセル化し、Webは対応するサーブレットサービスを見つけて、2つのオブジェクトHttpServletRequestとHttpServletResponseをその中に渡します。
  3. サービスプログラムは、これら2つのオブジェクトに対して処理計算とデータベースの相互作用を実行した後、これら2つのオブジェクトをWebコンテナに返します。
  4. Webコンテナは、2つのオブジェクトデータを解析し、Httpプロトコルの形式でクライアントブラウザに送信します。

最後に、ブラウザが情報を受信した後、HTTPプロトコルに従って解析するプロセス全体が完了します。

プログラマーは何ができるか

この一連のプロセスの場合、プログラマーは通常、HttpServletRequestオブジェクトとHttpServletResponseオブジェクトを処理するJavaWebの作成などのサーブレットサービスを作成します。Java Webは、初期のサーブレット+ JSPおよび今日のSSMから、モノリシックアーキテクチャからSpringboot + Springクラウドなどのマイクロサービスに進化しました。複雑なシステムには、メッセージングミドルウェア(RabbitMQなど)、キャッシングミドルウェア(Redisなど)、負荷分散ミドルウェア(Nginxなど)なども含まれる場合があります。
このシステム全体はサーブレットサービスに属しており、システムが処理する必要のあるオブジェクトはHttpServletRequestとHttpServletResponseです。これら2つのオブジェクトはメッセージングオブジェクトです。プログラムが解決する必要があるのは、メッセージの正しい処理、要求処理時の高い同時実行性、およびシステム例外下での高可用性です。

上記は個人的な理解に過ぎません。何か不適切なことがあれば、通りすがりの神々に助けてください。

おすすめ

転載: blog.csdn.net/weixin_43901067/article/details/106295855