实现一个能处理HTTP请求的服务器
一般来说,浏览器发送的HTTP请求内容包含:
GET /hello HTTP/1.1
Host: www.example.com
User-Agent: curl/7.88.1
Accept: */*
指出了请求的方法GET,主机www.example.com ,路径/hello
对于服务器来说,只需要解析请求,并对浏览器进行响应即可,这里输出响应:
HTTP/1.1 200 OK
Server: Simple HttpServer/1.0
Date: Fri, 07 Jul 2023 23:15:09 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 22
Connection: keep-alive
<h1>Hello, world.</h1>
那么实现HTTP Server的过程实际上就是:
- 接收浏览器发送的HTTP请求
- 解析HTTP请求
- 处理请求
- 发送HTTP响应
- 不断重复1-4步骤,直到TCP连接关闭
这里可以通过JDK内置的httpserver包实现,它主要提供了以下几个类:
- HttpServer: 通过指定IP地址和端口号,定义一个HTTP服务实例
- HttpHandler:处理HTTP请求的核心接口,通过实现handler()方法处理请求
- HttpExchange:读取HTTP请求的输入类,并将HTTP响应输出给它
public class SimpleHttpServer implements HttpHandler, AutoCloseable {
final Logger logger = LoggerFactory.getLogger(getClass());
public static void main(String[] args) {
String host = "0.0.0.0";
int port = 8080;
try (SimpleHttpServer connector = new SimpleHttpServer(host, port)) {
for (; ; ) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
final HttpServer httpServer;
final String host;
final int port;
public SimpleHttpServer(String host, int port) throws IOException {
this.host = host;
this.port = port;
this.httpServer = HttpServer.create(new InetSocketAddress(host, port), 0);
this.httpServer.createContext("/", this); // 注册路径和处理器
this.httpServer.start();
}
@Override
public void close() {
this.httpServer.stop(3);
}
@Override
public void handle(HttpExchange exchange) throws IOException {
String method = exchange.getRequestMethod();
URI uri = exchange.getRequestURI();
String path = uri.getPath();
String query = uri.getRawQuery();
Headers respHeaders = exchange.getResponseHeaders();
respHeaders.set("Content-Type", "text/html; charset=utf-8");
// 设置200响应:
exchange.sendResponseHeaders(200, 0);
String s = "<h1>Hello, world.</h1><p>" + LocalDateTime.now().withNano(0) + "</p>";
try (OutputStream out = exchange.getResponseBody()) {
out.write(s.getBytes(StandardCharsets.UTF_8));
}
}
}
启动服务后,在浏览器中输入localhost:8080就可以看见响应
总结: 通过JDK内置的httpserver包实现了一个简易的能处理http请求的服务器