一、概述
隨着人們的需求發展,web技術的發展也經歷了多個階段,下一個階段總是伴隨着解決上一階段的問題,從靜態文本、動態執行、動態自動生成文本,web應用,到web2.0,本文就詳細描述這些階段的特征。
特別說明,本文主要是參考《Tomcat 與java web開發技術詳解》(第二版)孫衛琴著,此書介紹的非常詳細。
簡述一下,web發展的目前4個階段如下:
(1)靜態文檔階段。
(2)瀏覽器提供的用戶動態交互階段
(3)服務器端提供的用戶動態交互階段
(4)web應用階段
(5)web 2.0階段
二、靜態文檔階段。
1、特點:
用戶只能查看靜態HTML文檔,或者通過點擊超鏈接,看到的還是靜態文檔的內容,不能參與交互操作。
2、瀏覽器和服務器端的交互過程

3、代碼示例與運行結果
服務器端代碼:
1 package server; 2 import java.io.*; 3 import java.net.*; 4 5 public class HTTPServer{ 6 public static void main(String args[]) { 7 int port; 8 ServerSocket serverSocket; 9 10 try { 11 port = Integer.parseInt(args[0]); 12 }catch (Exception e) { 13 System.out.println("port = 8080 (默認)"); 14 port = 8080; //默認端口為8080 15 } 16 17 try{ 18 serverSocket = new ServerSocket(port); 19 System.out.println("服務器正在監聽端口:" + serverSocket.getLocalPort()); 20 21 while(true) { //服務器在一個無限循環中不斷接收來自客戶的TCP連接請求 22 try{ 23 //等待客戶的TCP連接請求 24 final Socket socket = serverSocket.accept(); 25 System.out.println("建立了與客戶的一個新的TCP連接,該客戶的地址為:"+ 26 socket.getInetAddress()+":" + socket.getPort()); 27 28 service(socket); //響應客戶請求 29 }catch(Exception e){e.printStackTrace();} 30 } //#while 31 }catch (Exception e) {e.printStackTrace();} 32 } 33 34 /** 響應客戶的HTTP請求 */ 35 public static void service(Socket socket)throws Exception{ 36 37 /*讀取HTTP請求信息*/ 38 InputStream socketIn=socket.getInputStream(); //獲得輸入流 39 Thread.sleep(500); //睡眠500毫秒,等待HTTP請求 40 int size=socketIn.available(); 41 byte[] requestBuffer=new byte[size]; 42 socketIn.read(requestBuffer); 43 String request=new String(requestBuffer); 44 System.out.println(request); //打印HTTP請求數據 45 46 /*解析HTTP請求*/ 47 //獲得HTTP請求的第一行 48 String firstLineOfRequest=request.substring(0,request.indexOf("\r\n")); 49 //解析HTTP請求的第一行 50 String[] parts=firstLineOfRequest.split(" "); 51 String getMethod = "GET"; 52 if(true != parts[0].equals("GET")) 53 { 54 System.out.println("client Bad request:" + parts[0] + " method length=" + parts[0].length() ); //打印錯誤的請求 55 System.out.println("correct request is:" + getMethod ); 56 } 57 58 String uri=parts[1]; //獲得HTTP請求中的uri 59 60 /*決定HTTP響應正文的類型*/ 61 String contentType; 62 if(uri.indexOf("html")!=-1 || uri.indexOf("htm")!=-1) 63 contentType="text/html"; 64 else if(uri.indexOf("jpg")!=-1 || uri.indexOf("jpeg")!=-1) 65 contentType="image/jpeg"; 66 else if(uri.indexOf("gif")!=-1) 67 contentType="image/gif"; 68 else 69 contentType="application/octet-stream"; 70 71 72 /*創建HTTP響應結果 */ 73 //HTTP響應的第一行 74 String responseFirstLine="HTTP/1.1 200 OK\r\n"; 75 //HTTP響應頭 76 String responseHeader="Content-Type:"+contentType+"\r\n\r\n"; 77 //獲得讀取響應正文數據的輸入流 78 InputStream in=HTTPServer.class.getResourceAsStream("root/"+uri); 79 80 /*發送HTTP響應結果 */ 81 OutputStream socketOut=socket.getOutputStream(); //獲得輸出流 82 //發送HTTP響應的第一行 83 socketOut.write(responseFirstLine.getBytes()); 84 //發送HTTP響應的頭 85 socketOut.write(responseHeader.getBytes()); 86 //發送HTTP響應的正文 87 int len=0; 88 byte[] buffer=new byte[128]; 89 while((len=in.read(buffer))!=-1) 90 socketOut.write(buffer,0,len); 91 92 Thread.sleep(1000); //睡眠1秒,等待客戶接收HTTP響應結果 93 socket.close(); //關閉TCP連接 94 95 } 96 } 97 98 99 100 101 /**************************************************** 102 * 作者:孫衛琴 * 103 * 來源:<<Tomcat與Java Web開發技術詳解>> * 104 * 技術支持網址:www.javathinker.org * 105 ***************************************************/
客戶端代碼:
1 package client; 2 import java.net.*; 3 import java.io.*; 4 import java.util.*; 5 6 public class HTTPClient { 7 public static void main(String args[]){ 8 //確定HTTP請求的uri 9 String uri="index.htm"; 10 if(args.length !=0)uri=args[0]; 11 12 doGet("localhost",8080,uri); //按照GET請求方式訪問HTTPServer 13 } 14 15 /** 按照GET請求方式訪問HTTPServer */ 16 public static void doGet(String host,int port,String uri){ 17 Socket socket=null; 18 19 try{ 20 socket=new Socket(host,port); //與HTTPServer建立FTP連接 21 }catch(Exception e){e.printStackTrace();} 22 23 try{ 24 /*創建HTTP請求 */ 25 StringBuffer sb=new StringBuffer("GET1 "+uri+" HTTP/1.1\r\n"); 26 sb.append("Accept: */*\r\n"); 27 sb.append("Accept-Language: zh-cn\r\n"); 28 sb.append("Accept-Encoding: gzip, deflate\r\n"); 29 sb.append("User-Agent: HTTPClient\r\n"); 30 sb.append("Host: localhost:8080\r\n"); 31 sb.append("Connection: Keep-Alive\r\n\r\n"); 32 33 /*發送HTTP請求*/ 34 OutputStream socketOut=socket.getOutputStream(); //獲得輸出流 35 socketOut.write(sb.toString().getBytes()); 36 37 Thread.sleep(2000); //睡眠2秒,等待響應結果 38 39 /*接收響應結果*/ 40 InputStream socketIn=socket.getInputStream(); //獲得輸入流 41 int size=socketIn.available(); 42 byte[] buffer=new byte[size]; 43 socketIn.read(buffer); 44 System.out.println(new String(buffer)); //打印響應結果 45 46 }catch(Exception e){ 47 e.printStackTrace(); 48 }finally{ 49 try{ 50 socket.close(); 51 }catch(Exception e){e.printStackTrace();} 52 } 53 } //#doGet() 54 } 55 56 57 58 59 /**************************************************** 60 * 作者:孫衛琴 * 61 * 來源:<<Tomcat與Java Web開發技術詳解>> * 62 * 技術支持網址:www.javathinker.org * 63 ***************************************************/
運行結果:
4、總結:
靜態文檔,包括靜態的html文檔,txt文檔、圖片、音頻、視頻文件等,凡是早就存在於服務器端文件系統中的文件都認為是靜態文本。
三、瀏覽器提供的用戶交互階段
1、特點:
用戶可以參與交互操作,方便了客戶使用。
2、瀏覽器和服務器端的交互過程


3、代碼示例與運行結果
服務器端代碼:
同上,不過,需要在服務器的文件系統root目錄下存放JAVA Applet、ASP、JSP等文件,以便客戶端來獲取。
客戶端代碼:
不變,直接按照hello3.html中的tag標記,<applet code=HelloApplet.class ... > 進行運行即可。
運行結果:
略。
4、總結:
這個階段已經初步滿足客戶需要,不過,由於這些腳本文件都是在瀏覽器上執行,對客戶的瀏覽器要求越來越高,一旦用戶瀏覽器版本或者插件不支持,則無法參與交互,
所以,需要解決此問題。
四、服務器端提供的用戶交互階段
1、特點:
用戶參與交互操作,所有的運算都是在服務器端提供的,對客戶端而言就是簡單的運行html文件,對瀏覽器要求低。
2、瀏覽器和服務器端的交互過程

3、代碼示例與運行結果
服務器端代碼:
幾點說明,
第一、Servlet是JAVA的一個接口,服務器端新寫的java類必須實現這個接口(implements Servlet),像下面這種格式:
1 package server; 2 import java.io.*; 3 public class HelloServlet implements Servlet{ 4 public void init()throws Exception{ 5 System.out.println("HelloServlet is inited"); 6 } 7 public void service(byte[] requestBuffer, OutputStream out)throws Exception{ 8 String request=new String(requestBuffer); 9 10 //獲得HTTP請求的第一行 11 String firstLineOfRequest=request.substring(0,request.indexOf("\r\n")); 12 //解析HTTP請求的第一行 13 String[] parts=firstLineOfRequest.split(" "); 14 String method=parts[0]; //獲得HTTP請求中的請求方式 15 String uri=parts[1]; //獲得HTTP請求中的uri 16 17 18 /*獲得請求參數username */ 19 String username=null; 20 if(method.equalsIgnoreCase("get") && uri.indexOf("username=")!=-1){ 21 22 /*假定uri="servlet/HelloServlet?username=Tom&password=1234"*/ 23 //parameters="username=Tom&password=1234" 24 String parameters=uri.substring(uri.indexOf("?"),uri.length()); 25 26 //parts={"username=Tom","password=1234"}; 27 parts=parameters.split("&"); 28 //parts={"username","Tom"}; 29 parts=parts[0].split("="); 30 username=parts[1]; 31 } 32 if(method.equalsIgnoreCase("post")){ 33 int locate=request.indexOf("\r\n\r\n"); 34 //獲得響應正文 35 String content=request.substring(locate+4,request.length()); 36 if(content.indexOf("username=")!=-1){ 37 /*假定content="username=Tom&password=1234"*/ 38 //parts={"username=Tom","password=1234"}; 39 parts=content.split("&"); 40 //parts={"username","Tom"}; 41 parts=parts[0].split("="); 42 username=parts[1]; 43 } 44 } 45 46 /*創建並發送HTTP響應*/ 47 //發送HTTP響應第一行 48 out.write("HTTP/1.1 200 OK\r\n".getBytes()); 49 //發送HTTP響應頭 50 out.write("Content-Type:text/html\r\n\r\n".getBytes()); 51 //發送HTTP響應正文 52 out.write("<html><head><title>HelloWorld</title></head><body>".getBytes()); 53 out.write(new String("<h1>Hello:"+username+"</h1></body><head>").getBytes()); 54 55 } 56 } 57 58 59 60 /**************************************************** 61 * 作者:孫衛琴 * 62 * 來源:<<Tomcat與Java Web開發技術詳解>> * 63 * 技術支持網址:www.javathinker.org * 64 ***************************************************/
第二、服務器端必須把這個新寫的Servlet加載到內存中,按照如下的格式:
1 package server; 2 import java.io.*; 3 import java.net.*; 4 import java.util.*; 5 public class HTTPServer1{ 6 private static Map servletCache=new HashMap(); 7 8 public static void main(String args[]) { 9 int port; 10 ServerSocket serverSocket; 11 12 try { 13 port = Integer.parseInt(args[0]); 14 }catch (Exception e) { 15 System.out.println("port = 8080 (默認)"); 16 port = 8080; //默認端口為8080 17 } 18 19 try{ 20 serverSocket = new ServerSocket(port); 21 System.out.println("服務器正在監聽端口:" + serverSocket.getLocalPort()); 22 23 while(true) { //服務器在一個無限循環中不斷接收來自客戶的TCP連接請求 24 try{ 25 //等待客戶的TCP連接請求 26 final Socket socket = serverSocket.accept(); 27 System.out.println("建立了與客戶的一個新的TCP連接,該客戶的地址為:"+ 28 socket.getInetAddress()+":" + socket.getPort()); 29 30 service(socket); //響應客戶請求 31 }catch(Exception e){e.printStackTrace();} 32 } //#while 33 }catch (Exception e) {e.printStackTrace();} 34 } 35 36 /** 響應客戶的HTTP請求 */ 37 public static void service(Socket socket)throws Exception{ 38 39 /*讀取HTTP請求信息*/ 40 InputStream socketIn=socket.getInputStream(); //獲得輸入流 41 Thread.sleep(500); //睡眠500毫秒,等待HTTP請求 42 int size=socketIn.available(); 43 byte[] requestBuffer=new byte[size]; 44 socketIn.read(requestBuffer); 45 String request=new String(requestBuffer); 46 System.out.println(request); //打印HTTP請求數據 47 48 /*解析HTTP請求*/ 49 //獲得HTTP請求的第一行 50 String firstLineOfRequest=request.substring(0,request.indexOf("\r\n")); 51 //解析HTTP請求的第一行 52 String[] parts=firstLineOfRequest.split(" "); 53 String uri=parts[1]; //獲得HTTP請求中的uri 54 55 /*如果請求訪問Servlet,則動態調用Servlet對象的service()方法*/ 56 if(uri.indexOf("servlet")!=-1){ 57 //獲得Servlet的名字 58 String servletName=null; 59 if(uri.indexOf("?")!=-1) 60 servletName=uri.substring(uri.indexOf("servlet/")+8,uri.indexOf("?")); 61 else 62 servletName=uri.substring(uri.indexOf("servlet/")+8,uri.length()); 63 //嘗試從Servlet緩存中獲取Servlet對象 64 Servlet servlet=(Servlet)servletCache.get(servletName); 65 //如果Servlet緩存中不存在Servlet對象,就創建它,並把它存放在Servlet緩存中 66 if(servlet==null){ 67 servlet=(Servlet)Class.forName("server."+servletName).newInstance(); 68 servlet.init();//先調用Servlet對象的init()方法 69 servletCache.put(servletName,servlet); 70 } 71 72 //調用Servlet的service()方法 73 servlet.service(requestBuffer,socket.getOutputStream()); 74 75 Thread.sleep(1000); //睡眠1秒,等待客戶接收HTTP響應結果 76 socket.close(); //關閉TCP連接 77 return; 78 } 79 80 81 /*決定HTTP響應正文的類型*/ 82 String contentType; 83 if(uri.indexOf("html")!=-1 || uri.indexOf("htm")!=-1) 84 contentType="text/html"; 85 else if(uri.indexOf("jpg")!=-1 || uri.indexOf("jpeg")!=-1) 86 contentType="image/jpeg"; 87 else if(uri.indexOf("gif")!=-1) 88 contentType="image/gif"; 89 else 90 contentType="application/octet-stream"; 91 92 93 /*創建HTTP響應結果 */ 94 //HTTP響應的第一行 95 String responseFirstLine="HTTP/1.1 200 OK\r\n"; 96 //HTTP響應頭 97 String responseHeader="Content-Type:"+contentType+"\r\n\r\n"; 98 //獲得讀取響應正文數據的輸入流 99 InputStream in=HTTPServer1.class.getResourceAsStream("root/"+uri); 100 101 /*發送HTTP響應結果 */ 102 OutputStream socketOut=socket.getOutputStream(); //獲得輸出流 103 //發送HTTP響應的第一行 104 socketOut.write(responseFirstLine.toString().getBytes()); 105 //發送HTTP響應的頭 106 socketOut.write(responseHeader.toString().getBytes()); 107 //發送HTTP響應的正文 108 int len=0; 109 byte[] buffer=new byte[128]; 110 while((len=in.read(buffer))!=-1) 111 socketOut.write(buffer,0,len); 112 113 Thread.sleep(1000); //睡眠1秒,等待客戶接收HTTP響應結果 114 socket.close(); //關閉TCP連接 115 116 } 117 } 118 119 120 121 122 /**************************************************** 123 * 作者:孫衛琴 * 124 * 來源:<<Tomcat與Java Web開發技術詳解>> * 125 * 技術支持網址:www.javathinker.org * 126 ***************************************************/
客戶端代碼:
無特殊。
運行結果:
服務器端先運行,
客戶端在瀏覽器中輸入:
http://localhost:8080/servlet/HelloServlet?username=Tom
五、web 2.0階段
1、特點:
在web1.0中,廣大用戶主要是Web提供的信息的消費者,用戶通過瀏覽器來獲取信息,而Web2.0則強調全名織網,發動廣大民眾來共同為Web提供信息來源,Web2.0注重用戶與Web的交互,用戶既是Web信息的消費者,也是Web信息的制造者,典型的應用是:博客、RSS(站點摘要)、WIKI、SNS(社交網絡軟件)、IM(及時通信)如QQ、MSN。
七、處理HTTP請求參數和HTML表單
1、HTTP表單就是指客戶端發送GET或者POST請求時,在HTML的文本框,或者其他的控件輸入的參數值,就是表單的意思,例如下面的用戶名、密碼。例如:
用GET方法時,GET /servlet/HelloServlet?username=Tom&password=1234&submit=submit HTTP/1.1
用POST方法時,POST /servlet/HelloServlet HTTP/1.1
......
username=Tom&password=1234&submit=submit
