应用程序的入口在HttpServer类中。main()方法创建一个HttpServer实例,然后调用await()方法。服务器会在指定的端口上等待HTTP请求,对其进行处理,然后发送响应信息回客户端。
package com.forcht.webApplication;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
/**
*
* @author forcht
* 一个Http服务器
*/
public class HttpServer {
public static final String WEB_ROOT=
System.getProperty("user.dir")+File.separator+"webroot";
private static final String SHUTDOWN_COMMAND="/SHUTDOWN";
private boolean shutdown=false;
public static void main(String[] args) {
HttpServer server=new HttpServer();
server.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);
}
while(!shutdown) {
Socket socket=null;
InputStream input=null;
OutputStream output=null;
try {
socket = serverSocket.accept();
input=socket.getInputStream();
output=socket.getOutputStream();
//将请求交给request处理
Request request=new Request(input);
request.parse();
//创建一个response类来响应客户端
Response response=new Response(output);
response.setRequest(request);
response.sendStaticResource();
socket.close();
//判断是或是关闭服务器的请求
shutdown=request.getUri().equals(SHUTDOWN_COMMAND);
} catch (IOException e) {
e.printStackTrace();
continue;
}
}
}
}
request类
package com.forcht.webApplication;
/**
*
* @author forcht
*
*/
import java.io.IOException;
import java.io.InputStream;
public class Request {
private InputStream input;
private String uri;
public Request(InputStream input) {
this.input=input;
}
/**
* 解析请求
* 只是将请求打印出来
*/
public void parse() {
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.println(request.toString());
uri=parseUri(request.toString());
}
/**
* 获取请求的行中的url
* @param requestString
* @return
*/
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;
}
public String getUri() {
return uri;
}
}
response类
package com.forcht.webApplication;
/**
*
* @author forcht
*
*/
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
public class Response {
private static final int BUFFER_SIZE=1024;
Request request;
OutputStream output;
public Response(OutputStream output) {
this.output=output;
}
public void setRequest(Request request) {
this.request=request;
}
/**
* 读取请求的静态文件
* 并发送给客户端
* 如果文件不存在则返回文件不存在的信息
* @throws IOException
*/
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 {
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) {
e.printStackTrace();
}finally {
if(fis!=null) {
fis.close();
}
}
}
}
下面进行测试
在工程下创建一个webroot目录,在该目录下编写一个index.html文件
如果请求的文件不存在则显示
更多源码在https://gitee.com/hai_tang/MyTomcat.git