一、概述
随着人们的需求发展,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