基于Java实现Http服务器之二

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

在上篇文章中我们介绍了Http协议的基本知识,以及Java中两个重要的类Socket和SocketServer类,下面我们将主要介绍如何实现一个基于java的Http服务器。

Http服务器主要由三个类构成:HttpServer、Request和Response。其中程序的入口在HttpServer类,它调用await()方法,使得Server开始等候客户端的连接。当客户端连接后,它将把静态的页面内容发送给客户端浏览器。下面分别介绍这三个类:

1:HttpServer类

HttpServer需要有一个服务器的根目录这在WEB_ROOT变量中定义的:

public static final String WEB_ROOT =System.getProperty("user.dir") + File.separator + "webroot";当我们运行服务器的时候可以通过-D选项指定环境变量user.dir的值。这个类中最重要的方法就是await()方法,内容如下:

public void await() {

ServerSocket serverSocket = null;

int port = 8080;

try {

serverSocket = new ServerSocket(port, 1, InetAddress.getByName("127.0.0.1"));

}

catch (IOException e) {

e.printStackTrace();

System.exit(1);

}

// Loop waiting for a request

while (!shutdown) {

Socket socket = null;

InputStream input = null;

OutputStream output = null;

try {

socket = serverSocket.accept();

input = socket.getInputStream();

output = socket.getOutputStream();

// create Request object and parse

Request request = new Request(input);

request.parse();

// create Response object

Response response = new Response(output);

response.setRequest(request);

response.sendStaticResource();

// Close the socket

socket.close();

//check if the previous URI is a shutdown command

shutdown = request.getUri().equals(SHUTDOWN_COMMAND);

}

catch (Exception e) {

e.printStackTrace();

continue;

}

}

}

await()方法内构造一个ServerSocket的实例,等客户端连接进来的时候把socket.getInputStream()传递给Request类进行解析,把socket.getOutputStream()传递给Response类,然后再把request对象传递给Response,最后调用Response.sendStaticResource()方法发送数据给客户端。socket.close()后监测是不是接受到了关闭Server的命令,如果是的话跳出循环结束程序。

2. Request类

Request类的主要目的是对http请求进行封装,它有一个InputStream类型参数的构造器

public Request(InputStream input) {

this.input = input;

}

同时它还有一个重要的String类型的成员变量uri,Request的目的就是从inputStream中提取uri,这是由两个函数实现的

public void parse() {

// Read a set of characters from the socket

StringBuffer request = new StringBuffer(2048);

int i;

byte[] buffer = new byte[2048];

try {

i = input.read(buffer);

}

catch (IOException e) {

e.printStackTrace();

i = -1;

}

for (int j=0; j<i; j++) {

request.append((char) buffer[j]);

}

System.out.print(request.toString());

uri = parseUri(request.toString());

}

private String parseUri(String requestString) {

int index1, index2;

index1 = requestString.indexOf(' ');

if (index1 != -1) {

index2 = requestString.indexOf(' ', index1 + 1);

if (index2 > index1)

return requestString.substring(index1 + 1, index2);

}

return null;

}

其中parseUri(String request)方法是私有方法,它把String参数进行解析把两个空格之间的字符串返回,这是遵循Http请求的定义规则的,如果你不清楚可以参考基于java实现http服务器之一。

2.Response类

Response的两个重要的成员变量分别是OutputStream类型的output和Requeset类型的request,这个类的功能就是从Request的实例里面得到uri,然后和WEB_ROOT进行相加得到文件所在的绝对路径,然后读取这个文件的内容把它写入到socket.getOutputStream()里面去。

public void sendStaticResource() throws IOException {

byte[] bytes = new byte[BUFFER_SIZE];

FileInputStream fis = null;

try {

File file = new File(HttpServer.WEB_ROOT, request.getUri());

if (file.exists()) {

fis = new FileInputStream(file);

int ch = fis.read(bytes, 0, BUFFER_SIZE);

while (ch!=-1) {

output.write(bytes, 0, ch);

ch = fis.read(bytes, 0, BUFFER_SIZE);

}

}

else {

// file not found

String errorMessage = "HTTP/1.1 404 File Not Found\r\n" +

"Content-Type: text/html\r\n" +

"Content-Length: 23\r\n" +

"\r\n" +

"<h1>File Not Found</h1>";

output.write(errorMessage.getBytes());

}

}

catch (Exception e) {

// thrown if cannot instantiate a File object

System.out.println(e.toString() );

}

finally {

if (fis!=null)

fis.close();

}

}

下面说明如何运行这个应用程序,首先你从下面的地址取得源代码:http://www.onjava.com/onjava/2003/04/23/examples/HowWebServersWork.zip,把它解到你的D盘例如temp目录下,它包括三个目录src lib webroot其中webroot内有一个index.html文件供测试用。从Command中运行

cd temp

javac -d . src/ex01/pyrmont/*.java

这样在当前目录(d:\temp)会出现ex01/pyrmont目录,里面是编译得到的class文件,接下来运行

java -Duser.dir=d:\temp ex01.pyrmont.HttpServer

然后从浏览器输入http://localhost:8080/index.html,这样你就可以看到Server发送给你的静态页面index.html了。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
 
© 2005- 王朝網路 版權所有 導航