web 相信大家都不陌生,平常我們瀏覽網頁用的都是web服務。互聯網起初的web就是非常簡單的頁面,但是隨著客戶需求越來越複雜,需要的功能越來越多,我們的伺服器端需要處理的請求越來越多,需要區分不同的請求,還需要按照不同請求進行請求數據的提取以及資源的分配和運算還有邏輯的處理,最後還需要響應給客戶端 ...
web 相信大家都不陌生,平常我們瀏覽網頁用的都是web服務。互聯網起初的web就是非常簡單的頁面,但是隨著客戶需求越來越複雜,需要的功能越來越多,我們的伺服器端需要處理的請求越來越多,需要區分不同的請求,還需要按照不同請求進行請求數據的提取以及資源的分配和運算還有邏輯的處理,最後還需要響應給客戶端,這就使得伺服器端 代碼越來越複雜,實現越來越困難。根據以往的經驗,雙方進行通信只需要遵循一定的規則就可以很明確地知道各部分數據的含義,於是出現了網路更上層的應用協議(後面講的 HTTP 協議),規定 伺服器 端和客戶端通信的規則。客戶端請求 伺服器端和伺服器端響應客戶端,都按照固定的規則,那麼接收請求和相應數據這部分操作就可以固定下來,交給特定的一段代碼來執行,從而減少 伺服器端的代碼量,於是出現了各種web框架;如果大家想瞭解更加深入的話,就去瞭解web的發展歷程吧,其中有不少有趣的小故事啊,這裡就不詳細贅述了。
一,socket通信
說起web,肯定離不開tcp協議和http協議(https協議較為複雜,暫時不在本章討論範圍之內)。http協議在後面,那什麼是tcp協議,cp協議就是網路的傳輸層面的東西,就是用來傳輸數據的,tcp協議相對安全可靠,主要連接過程如下圖,客戶端先發送一個SYN請求,包含一個隨機數seq,假設這個隨機數的值等於i。伺服器就會發送一個ACK請求,並且對這個隨機數加1,同時發給客戶端,客戶端收到服務端的ack之後也會向服務端發送一個ack(這裡只是大概描述了一下tcp三次握手,如果想詳細瞭解的話可以去看tcp/ip協議捲)
http是應用層的協議,它的傳輸層是tcp協議。可以說sock通信是web服務的底層通信,沒有socket也就沒有http協議,跟談不上web服務了
二,體系架構
主要有c/s 架構和b/s架構,c/s 主要由一般需要在客戶端安裝的應用程式和遠程伺服器組成的。它的優點是通信雙方的通信量較少,因為大部分信息存儲在本地,缺點是客戶端的維護和升級較為麻煩,一般適用於大型的系統。
b/s架構是由瀏覽器和伺服器組成的,優點是方便,隨時可以上網,缺點是通信量較大,相對於c/s不是特別的穩定;
c/s 架構
b/s架構
三,web應用程式的工作原理
web應用程式大致上分為兩種,即動態網站和靜態網站。靜態網站就是用HTML寫的靜態頁面,動態網站是根據用戶不同的請求動態的生成動態的不同的頁面發送給客戶端,通常使用HTML語言和動態腳本語言(ASP,PHP,JSP)等語言編寫。下麵的圖片來源於網路
在開發 Web 應用程式時,通常需要應用客戶端和伺服器端兩方面的技術。其中,客戶端應用的技術主要用於展現信息內容,而伺服器端應用的技術,則主要用於進行業務邏輯的處理和與資料庫的交互等。
四,HTTP協議
為了使互聯網的web服務茁壯的發展,讓客戶端和服務端共同的遵守一些協議,http就出現了。http協議可以說是最偉大的協議之一,主要有1.0版本,1.1版本和2.0版本。在瀏覽器中的書寫格式是http://127.0.0.1:80/mysite/index,主要由 http協議://ip地址:埠 / 資源地址 組成的,這也是常說的URL,URL也是URI的一種形式,有興趣的可以查一下URL和URI有什麼區別;
http的請求報文
請求格式:
請求行
請求頭1
請求頭2
.........
請求空行
請求正文
請求行由請求方式(get和post),請求資源地址,協議(http/1.1) 組成
請求頭由報頭域組成 每一個報頭域都是由名字+“:”+空格+值組成,消息報頭域的名字是大小寫無關的。
請求正文(也有的叫請求體):只有post有請求正文,get是沒有的
註意:請求頭和請求正文之間必須有一個空白行的。
請求頭
http的響應報文
響應格式:
狀態行
響應頭1
響應頭2
..........
響應空行
響應正文
狀態行由協議(http/1.1 狀態碼 狀態碼的描述)
響應頭由報頭域組成 每一個報頭域都是由名字+“:”+空格+值組成,消息報頭域的名字是大小寫無關的。
響應正文 一般由HTML組成
註意:響應頭與響應正文之間必須有一個空白行
響應頭
響應正文
五,第一servlet的實現
Servlet 是 Server 與 Applet 的縮寫,是服務端小程式的意思。使用 Java 語言編寫的服務 器端程式,可以像生成動態的 WEB 頁,Servlet 主要運行在伺服器端,並由伺服器調用執行, 是一種按照 Servlet 標準來開發的類。 是 SUN 公司提供的一門用於開發動態 Web 資源的技 術。 (言外之意:要實現 web 開發,需要實現 Servlet 標準)Servlet 本質上也是 Java 類,但要遵循 Servlet 規範進行編寫,沒有 main()方法,它的創 建、使用、銷毀都由 Servlet 容器進行管理(如 Tomcat)。(言外之意:寫自己的類,不用寫 main 方法,別人自動調用)Servlet 是和 HTTP 協議是緊密聯繫的,其可以處理 HTTP 協議相關的所有內容。這也是 Servlet 應用廣泛的原因之一。提供了 Servlet 功能的伺服器,叫做 Servlet 容器,其常見容器有很多,如Tomcat, Jetty, WebLogic Server, WebSphere, JBoss 等。
創建servlet的三種方式:
第一種,繼承HttpServlet
1 package test; 2 3 import java.io.IOException; 4 import javax.servlet.ServletException; 5 import javax.servlet.http.HttpServlet; 6 import javax.servlet.http.HttpServletRequest; 7 import javax.servlet.http.HttpServletResponse; 8 9 public class Servlet01 extends HttpServlet { 10 11 @Override 12 public void init() throws ServletException { 13 System.out.println("我servlet01誕生了"); 14 15 } 16 17 @Override 18 protected void service(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException { 19 System.out.println("hello world"); 20 } 21 22 @Override 23 public void destroy() { 24 System.out.println("我servlet01要圓寂了"); 25 } 26 27 28 }View Code
第二方式 ,繼承GenericServlet
1 package test; 2 3 import java.io.IOException; 4 5 import javax.servlet.GenericServlet; 6 import javax.servlet.ServletException; 7 import javax.servlet.ServletRequest; 8 import javax.servlet.ServletResponse; 9 import javax.servlet.http.HttpServlet; 10 import javax.servlet.http.HttpServletResponse; 11 12 public class Servlet02 extends GenericServlet{ 13 @Override 14 public void init() throws ServletException { 15 System.out.println("我servlet02誕生了"); 16 } 17 18 @Override 19 public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { 20 System.out.println("service...servlet02...."); 21 HttpServletResponse hsr=(HttpServletResponse)res; 22 hsr.getWriter().write("hello world"); 23 24 } 25 26 @Override 27 public void destroy() { 28 System.out.println("我servlet02要走向死神的懷抱了"); 29 } 30 31 32 }View Code
第三種方式,實現Servlet介面
1 package test; 2 3 import java.io.IOException; 4 import javax.servlet.Servlet; 5 import javax.servlet.ServletConfig; 6 import javax.servlet.ServletException; 7 import javax.servlet.ServletRequest; 8 import javax.servlet.ServletResponse; 9 10 public class Servlet03 implements Servlet{ 11 12 @Override 13 public void init(ServletConfig config) throws ServletException { 14 System.out.println("servlet03的初試化"); 15 16 } 17 18 @Override 19 public ServletConfig getServletConfig() { 20 // TODO Auto-generated method stub 21 return null; 22 } 23 24 @Override 25 public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { 26 // TODO Auto-generated method stub 27 System.out.println("servlet03。。。。。"); 28 } 29 30 @Override 31 public String getServletInfo() { 32 // TODO Auto-generated method stub 33 return null; 34 } 35 36 @Override 37 public void destroy() { 38 // TODO Auto-generated method stub 39 System.out.println("servlet03的銷毀。。。。。。。"); 40 } 41 42 }View Code
servlet的工作原理
執行過程客戶端發出請求 根據 web.xml 文件的配置,找到對應的讀取中的值 找到對應的 找到該 class 並載入執行該 class,返回結果 由 Web 伺服器將結果響應給客戶端
web.xml的配置如下:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>test</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <servlet> <servlet-name>Servlet01</servlet-name> <servlet-class>test.Servlet01</servlet-class> </servlet> <servlet-mapping> <servlet-name>Servlet01</servlet-name> <url-pattern>/s01</url-pattern> </servlet-mapping> <servlet> <servlet-name>Servlet02</servlet-name> <servlet-class>test.Servlet02</servlet-class> </servlet> <servlet-mapping> <servlet-name>Servlet02</servlet-name> <url-pattern>/s02</url-pattern> </servlet-mapping> <servlet> <servlet-name>Servlet03</servlet-name> <servlet-class>test.Servlet03</servlet-class> </servlet> <servlet-mapping> <servlet-name>Servlet03</servlet-name> <url-pattern>/s03</url-pattern> </servlet-mapping> </web-app>View Code
servlet的生命周期
Servlet 沒有 main()方法,不能獨立運行,它的運行完全由 Servlet 引擎來控制和調度。 所謂生命周期,指的是 servlet 容器何時創建 servlet 實例、何時調用其方法進行請求的處理、 何時並銷毀其實例的整個過程。(此處討論預設的生命周期)實例和初始化時機當請求到達容器時,容器查找該 servlet 對象是否存在,如果不存在,則會
創建實例並 進行初始化。就緒/調用/服務階段有請求到達容器,容器調用 servlet 對象的 service()方法,處理請求的方法在整個聲明周 期中可以被多次調用;HttpServlet 的 service()方法,會依據請求方式來調用 doGet()或者 doPost()方法。但是, 這兩個 do 方法預設情況下,會拋出異常,需要子類去 override。
銷毀時機當容器關閉時(應用程式停止時),會將程式中的 Servlet 實例進行銷毀。上述的生命周期可以通過 Servlet 中的生命周期方法來觀察。在 Servlet 中有三個生命周 期方法,不由用戶手動調用,而是在特定的時機有容器自動調用,觀察這三個生命周期方法 即可觀察到 Servlet 的生命周期。init 方法,在 Servlet 實例創建之後執行(證明該 Servlet 有實例創建了)。
servlet的配置
Servlet 除了配置基本的訪問信息,還可以配置初始化參數,自啟動等,並且一個 Servlet 可以配置多個訪問路徑(),還可以使用通配符“ * ”
xml配置初試化參數
<servlet> <servlet-name>Servlet03</servlet-name> <servlet-class>test.Servlet03</servlet-class> <init-param> <param-name>name</param-name> <param-value>liu</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>Servlet03</servlet-name> <url-pattern>/s03</url-pattern> </servlet-mapping>View Code
servlet的init方法中列印初始化參數信息
@Override public void init(ServletConfig config) throws ServletException { System.out.println("servlet03的初試化"); String name=config.getInitParameter("name"); System.out.println(name); }View Code
<load-on-startup>2</load-on-startup>表示容器啟動時就要創建servlet的對象,2表示啟動的等級,數字1等級最高,即容器啟動時,先創建1等級的servlet對象,當1等級的創建完成之後再創建2等級的servlet對象;