一、概述
随着人们的需求发展,web技术的发展也经历了多个阶段,下一个阶段总是伴随着解决上一阶段的问题,从静态文本、动态执行、动态自动生成文本,web应用,到web2.0,本文就详细描述这些阶段的特征。
特别说明,本文主要是参考《Tomcat 与java web开发技术详解》(第二版)孙卫琴著,此书介绍的非常详细。
简述一下,web发展的目前4个阶段如下:
(1)静态文档阶段。
(2)浏览器提供的用户动态交互阶段
(3)服务器端提供的用户动态交互阶段
(4)web应用阶段
(5)web 2.0阶段
二、静态文档阶段。
1、特点:
用户只能查看静态HTML文档,或者通过点击超链接,看到的还是静态文档的内容,不能参与交互操作。
2、浏览器和服务器端的交互过程
3、代码示例与运行结果
服务器端代码:
package server;
import java.io.*;
import java.net.*; public class HTTPServer{
public static void main(String args[]) {
int port;
ServerSocket serverSocket; try {
port = Integer.parseInt(args[0]);
}catch (Exception e) {
System.out.println("port = 8080 (默认)");
port = 8080; //默认端口为8080
} try{
serverSocket = new ServerSocket(port);
System.out.println("服务器正在监听端口:" + serverSocket.getLocalPort()); while(true) { //服务器在一个无限循环中不断接收来自客户的TCP连接请求
try{
//等待客户的TCP连接请求
final Socket socket = serverSocket.accept();
System.out.println("建立了与客户的一个新的TCP连接,该客户的地址为:"+
socket.getInetAddress()+":" + socket.getPort()); service(socket); //响应客户请求
}catch(Exception e){e.printStackTrace();}
} //#while
}catch (Exception e) {e.printStackTrace();}
} /** 响应客户的HTTP请求 */
public static void service(Socket socket)throws Exception{ /*读取HTTP请求信息*/
InputStream socketIn=socket.getInputStream(); //获得输入流
Thread.sleep(500); //睡眠500毫秒,等待HTTP请求
int size=socketIn.available();
byte[] requestBuffer=new byte[size];
socketIn.read(requestBuffer);
String request=new String(requestBuffer);
System.out.println(request); //打印HTTP请求数据 /*解析HTTP请求*/
//获得HTTP请求的第一行
String firstLineOfRequest=request.substring(0,request.indexOf("\r\n"));
//解析HTTP请求的第一行
String[] parts=firstLineOfRequest.split(" ");
String getMethod = "GET";
if(true != parts[0].equals("GET"))
{
System.out.println("client Bad request:" + parts[0] + " method length=" + parts[0].length() ); //打印错误的请求
System.out.println("correct request is:" + getMethod );
} String uri=parts[1]; //获得HTTP请求中的uri /*决定HTTP响应正文的类型*/
String contentType;
if(uri.indexOf("html")!=-1 || uri.indexOf("htm")!=-1)
contentType="text/html";
else if(uri.indexOf("jpg")!=-1 || uri.indexOf("jpeg")!=-1)
contentType="image/jpeg";
else if(uri.indexOf("gif")!=-1)
contentType="image/gif";
else
contentType="application/octet-stream"; /*创建HTTP响应结果 */
//HTTP响应的第一行
String responseFirstLine="HTTP/1.1 200 OK\r\n";
//HTTP响应头
String responseHeader="Content-Type:"+contentType+"\r\n\r\n";
//获得读取响应正文数据的输入流
InputStream in=HTTPServer.class.getResourceAsStream("root/"+uri); /*发送HTTP响应结果 */
OutputStream socketOut=socket.getOutputStream(); //获得输出流
//发送HTTP响应的第一行
socketOut.write(responseFirstLine.getBytes());
//发送HTTP响应的头
socketOut.write(responseHeader.getBytes());
//发送HTTP响应的正文
int len=0;
byte[] buffer=new byte[128];
while((len=in.read(buffer))!=-1)
socketOut.write(buffer,0,len); Thread.sleep(1000); //睡眠1秒,等待客户接收HTTP响应结果
socket.close(); //关闭TCP连接 }
} /****************************************************
* 作者:孙卫琴 *
* 来源:<<Tomcat与Java Web开发技术详解>> *
* 技术支持网址:www.javathinker.org *
***************************************************/
客户端代码:
package client;
import java.net.*;
import java.io.*;
import java.util.*; public class HTTPClient {
public static void main(String args[]){
//确定HTTP请求的uri
String uri="index.htm";
if(args.length !=0)uri=args[0]; doGet("localhost",8080,uri); //按照GET请求方式访问HTTPServer
} /** 按照GET请求方式访问HTTPServer */
public static void doGet(String host,int port,String uri){
Socket socket=null; try{
socket=new Socket(host,port); //与HTTPServer建立FTP连接
}catch(Exception e){e.printStackTrace();} try{
/*创建HTTP请求 */
StringBuffer sb=new StringBuffer("GET1 "+uri+" HTTP/1.1\r\n");
sb.append("Accept: */*\r\n");
sb.append("Accept-Language: zh-cn\r\n");
sb.append("Accept-Encoding: gzip, deflate\r\n");
sb.append("User-Agent: HTTPClient\r\n");
sb.append("Host: localhost:8080\r\n");
sb.append("Connection: Keep-Alive\r\n\r\n"); /*发送HTTP请求*/
OutputStream socketOut=socket.getOutputStream(); //获得输出流
socketOut.write(sb.toString().getBytes()); Thread.sleep(2000); //睡眠2秒,等待响应结果 /*接收响应结果*/
InputStream socketIn=socket.getInputStream(); //获得输入流
int size=socketIn.available();
byte[] buffer=new byte[size];
socketIn.read(buffer);
System.out.println(new String(buffer)); //打印响应结果 }catch(Exception e){
e.printStackTrace();
}finally{
try{
socket.close();
}catch(Exception e){e.printStackTrace();}
}
} //#doGet()
} /****************************************************
* 作者:孙卫琴 *
* 来源:<<Tomcat与Java Web开发技术详解>> *
* 技术支持网址:www.javathinker.org *
***************************************************/
运行结果:
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),像下面这种格式:
package server;
import java.io.*;
public class HelloServlet implements Servlet{
public void init()throws Exception{
System.out.println("HelloServlet is inited");
}
public void service(byte[] requestBuffer, OutputStream out)throws Exception{
String request=new String(requestBuffer); //获得HTTP请求的第一行
String firstLineOfRequest=request.substring(0,request.indexOf("\r\n"));
//解析HTTP请求的第一行
String[] parts=firstLineOfRequest.split(" ");
String method=parts[0]; //获得HTTP请求中的请求方式
String uri=parts[1]; //获得HTTP请求中的uri /*获得请求参数username */
String username=null;
if(method.equalsIgnoreCase("get") && uri.indexOf("username=")!=-1){ /*假定uri="servlet/HelloServlet?username=Tom&password=1234"*/
//parameters="username=Tom&password=1234"
String parameters=uri.substring(uri.indexOf("?"),uri.length()); //parts={"username=Tom","password=1234"};
parts=parameters.split("&");
//parts={"username","Tom"};
parts=parts[0].split("=");
username=parts[1];
}
if(method.equalsIgnoreCase("post")){
int locate=request.indexOf("\r\n\r\n");
//获得响应正文
String content=request.substring(locate+4,request.length());
if(content.indexOf("username=")!=-1){
/*假定content="username=Tom&password=1234"*/
//parts={"username=Tom","password=1234"};
parts=content.split("&");
//parts={"username","Tom"};
parts=parts[0].split("=");
username=parts[1];
}
} /*创建并发送HTTP响应*/
//发送HTTP响应第一行
out.write("HTTP/1.1 200 OK\r\n".getBytes());
//发送HTTP响应头
out.write("Content-Type:text/html\r\n\r\n".getBytes());
//发送HTTP响应正文
out.write("<html><head><title>HelloWorld</title></head><body>".getBytes());
out.write(new String("<h1>Hello:"+username+"</h1></body><head>").getBytes()); }
} /****************************************************
* 作者:孙卫琴 *
* 来源:<<Tomcat与Java Web开发技术详解>> *
* 技术支持网址:www.javathinker.org *
***************************************************/
第二、服务器端必须把这个新写的Servlet加载到内存中,按照如下的格式:
package server;
import java.io.*;
import java.net.*;
import java.util.*;
public class HTTPServer1{
private static Map servletCache=new HashMap(); public static void main(String args[]) {
int port;
ServerSocket serverSocket; try {
port = Integer.parseInt(args[0]);
}catch (Exception e) {
System.out.println("port = 8080 (默认)");
port = 8080; //默认端口为8080
} try{
serverSocket = new ServerSocket(port);
System.out.println("服务器正在监听端口:" + serverSocket.getLocalPort()); while(true) { //服务器在一个无限循环中不断接收来自客户的TCP连接请求
try{
//等待客户的TCP连接请求
final Socket socket = serverSocket.accept();
System.out.println("建立了与客户的一个新的TCP连接,该客户的地址为:"+
socket.getInetAddress()+":" + socket.getPort()); service(socket); //响应客户请求
}catch(Exception e){e.printStackTrace();}
} //#while
}catch (Exception e) {e.printStackTrace();}
} /** 响应客户的HTTP请求 */
public static void service(Socket socket)throws Exception{ /*读取HTTP请求信息*/
InputStream socketIn=socket.getInputStream(); //获得输入流
Thread.sleep(500); //睡眠500毫秒,等待HTTP请求
int size=socketIn.available();
byte[] requestBuffer=new byte[size];
socketIn.read(requestBuffer);
String request=new String(requestBuffer);
System.out.println(request); //打印HTTP请求数据 /*解析HTTP请求*/
//获得HTTP请求的第一行
String firstLineOfRequest=request.substring(0,request.indexOf("\r\n"));
//解析HTTP请求的第一行
String[] parts=firstLineOfRequest.split(" ");
String uri=parts[1]; //获得HTTP请求中的uri /*如果请求访问Servlet,则动态调用Servlet对象的service()方法*/
if(uri.indexOf("servlet")!=-1){
//获得Servlet的名字
String servletName=null;
if(uri.indexOf("?")!=-1)
servletName=uri.substring(uri.indexOf("servlet/")+8,uri.indexOf("?"));
else
servletName=uri.substring(uri.indexOf("servlet/")+8,uri.length());
//尝试从Servlet缓存中获取Servlet对象
Servlet servlet=(Servlet)servletCache.get(servletName);
//如果Servlet缓存中不存在Servlet对象,就创建它,并把它存放在Servlet缓存中
if(servlet==null){
servlet=(Servlet)Class.forName("server."+servletName).newInstance();
servlet.init();//先调用Servlet对象的init()方法
servletCache.put(servletName,servlet);
} //调用Servlet的service()方法
servlet.service(requestBuffer,socket.getOutputStream()); Thread.sleep(1000); //睡眠1秒,等待客户接收HTTP响应结果
socket.close(); //关闭TCP连接
return;
} /*决定HTTP响应正文的类型*/
String contentType;
if(uri.indexOf("html")!=-1 || uri.indexOf("htm")!=-1)
contentType="text/html";
else if(uri.indexOf("jpg")!=-1 || uri.indexOf("jpeg")!=-1)
contentType="image/jpeg";
else if(uri.indexOf("gif")!=-1)
contentType="image/gif";
else
contentType="application/octet-stream"; /*创建HTTP响应结果 */
//HTTP响应的第一行
String responseFirstLine="HTTP/1.1 200 OK\r\n";
//HTTP响应头
String responseHeader="Content-Type:"+contentType+"\r\n\r\n";
//获得读取响应正文数据的输入流
InputStream in=HTTPServer1.class.getResourceAsStream("root/"+uri); /*发送HTTP响应结果 */
OutputStream socketOut=socket.getOutputStream(); //获得输出流
//发送HTTP响应的第一行
socketOut.write(responseFirstLine.toString().getBytes());
//发送HTTP响应的头
socketOut.write(responseHeader.toString().getBytes());
//发送HTTP响应的正文
int len=0;
byte[] buffer=new byte[128];
while((len=in.read(buffer))!=-1)
socketOut.write(buffer,0,len); Thread.sleep(1000); //睡眠1秒,等待客户接收HTTP响应结果
socket.close(); //关闭TCP连接 }
} /****************************************************
* 作者:孙卫琴 *
* 来源:<<Tomcat与Java Web开发技术详解>> *
* 技术支持网址:www.javathinker.org *
***************************************************/
客户端代码:
无特殊。
运行结果:
服务器端先运行,
客户端在浏览器中输入:
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