前面我们自己实现了一个线程池,现在我们基于前面编写的线程池(http://blog.csdn.net/canot/article/details/50904001)编写一个支持并发访问的Web服务器来处理一些简单的HTTP请求/响应。
public class SimpleHttpServer {
//定义处理HttpRequest的线程池
static ThreadPool<HttpRequestHandler> threadPool = new DefaultThreadPool<HttpRequestHandler>();
static ServerSocket serverSocket;
//该Web服务器的路径
static String basePath;
//默认的端口号
static int port = 8080;
//启动服务器
public static void start() throws IOException {
serverSocket = new ServerSocket(port);
Socket client = null;
//获取客户端的连接
while ((client = serverSocket.accept()) != null) {
//生成一个job放入线程池执行
threadPool.execute(new HttpRequestHandler(client));
}
serverSocket.close();
}
static class HttpRequestHandler implements Runnable {
private Socket client;
public HttpRequestHandler(Socket client) {
this.client = client;
}
public void run() {
byte[] buff = new byte[1024];
BufferedReader br = null;
PrintWriter pw = null;
File directory = new File("");
String basePath = directory.getAbsolutePath();
int length = 0;
try {
//读取客户端发送的请求数据
br = new BufferedReader(new InputStreamReader(client.getInputStream()));
//获取请求行的第一行再解析出要请求的资源
String header = br.readLine();
String filePath = header.split(" ")[1];
//判断请求的资源的为html
if(filePath.endsWith("html")){
pw = new PrintWriter(client.getOutputStream());
//构造HTTP响应头信息
pw.println("HTTP/1.1 200 Ok");
pw.println("Server: wangxiServer");
pw.println("Content-Type: text/html;charset=UTF-8");
pw.println("");
//通过io流读取访问的资源,然后输出给客户端
InputStream is = new FileInputStream(new File(basePath,filePath));
while((length=is.read(buff))>0){
pw.println(new String(buff,0,length));
}
pw.flush();
//判断请求的资源的为jpg
}else if(filePath.endsWith("jpg")){
//获取要访问的图片流,把流的数据全部存在ByteArrayOutputStream中
ByteArrayOutputStream bos = new ByteArrayOutputStream();
InputStream is = new FileInputStream(new File(basePath,filePath));
while((length=is.read(buff))>0){
bos.write(buff, 0, length);
}
byte[] image = bos.toByteArray();
//构造HTTP响应头,输出给客户端
pw = new PrintWriter(client.getOutputStream());
pw.println("HTTP/1.1 200 Ok");
pw.println("Server: wangxiServer");
pw.println("Content-Type: image/jpeg");
pw.println("Content-Length:"+image.length);
pw.println("");
//输出图片流
client.getOutputStream().write(image, 0, image.length);
}else{
pw.println("HTTP/1.1 200 Ok");
pw.println("Server: wangxiServer");
pw.println("Content-Type: text/html;charset=UTF-8");
pw.println("");
pw.println("404 No Found");
pw.flush();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
启动该服务器:
public class TestMyService {
public static void main(String[] args) {
try {
SimpleHttpServer.start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
SimpleHttpServer在建立起与客户端的连接之后,并不会直接处理客户端的请求,而是把其封装成HttpRequestHandler并交给线程池处理。在线程池中则由Worker处理客户端请求的同时,SimpleHttpServer能够继续完成后续客户端连接的建立,并不会阻塞后续客户端的请求。
在该项目的根目录下建立a.html,并放置图片1.jpg:
<html>
<head>
<title></title>
</head>
<body>
<img src="http://localhost:8080/1.jpg"></img>
</body>
</html>
在浏览器中输入http://localhost:8080/a.html可以看到图片正常显示,则完成了处理html和jpg的HTTP请求。