Java实现的极简http服务器

前言

网上已经有很多文章了写这部分内容了。

但都没有符合自己心意的。
要么代码过长,实现丰富。
要么符合代码精练,但又不符合http协议要求。

这里写了一个20行左右示意原理的最小实现。
能基本反映http协议原理。

只达到

  • 能正常解析基本GET请求,能正常返回HTTP相应报文。

未实现功能:

  • 响应GET方法以外的方法
  • keep-alive头

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class Main {
public static void main(String[] args) throws Exception {
ServerSocket server = new ServerSocket(4000);
System.out.println("start...");
while (true) {
System.out.println("wait connection.....");
Socket socket = server.accept();
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter output = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
String line = input.readLine();
while (line != null && line.length() != 0) {
System.out.println(line);
line = input.readLine();
}
String responseFormat = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: %d\r\n\r\n%s";
String msg = "currentTimeMillis:" + System.currentTimeMillis();
output.write(String.format(responseFormat, msg.length(), msg));
input.close();
output.close();
socket.close();
}
}
}

分析

http是应用层的文本传输协议

  • 请求与响应分为两部分,http头与http体
  • http头除第一行以外,以key-value的方式
  • http头与http体之间是以两个回车换行(“\r\n”)来分隔的
  • http头通常会标识出http体的长度(还有chunk方式)

代码:

  • #3:监听端口
  • #7:等待连接
  • #11:当读到http头的末尾时,line长度会为0,做为http头结束条件。当然POST方式,可能还会传http体的内容,但简化版不考虑。
  • #15:建立一个响应头模板
  • #18-20: 关闭连接

写在后面的

这只是示意原理代码。
当时只为了实现自己访问指定url就执行指定shell,来做一个小模块。

平时用得是最多就是python -m SimpleHTTPServer来临时的创建一个web服务器。
java好像就没有提供这样类似的工具。