1. 概述
Java 18 引入了简易 Web 服务器(Simple Web Server),这是通过 JEP 408 实现的新特性。我们可以通过命令行工具和 API 两种方式使用它。
这个服务器专门用于提供静态文件服务,官方描述其适用于测试、原型开发和教学场景。它被设计得极其简单易用,不打算与 Apache Tomcat 或 Jetty 等功能完备的服务器竞争。
引入该工具的核心目标是:让开发者以最低门槛快速上手 Web 开发。
本文将深入解析简易 Web 服务器的工作原理和使用方式。
2. jwebserver 命令行工具
2.1. 启动服务
最简单的启动方式就是使用内置的命令行工具 jwebserver
。直接执行 jwebserver
命令即可启动服务器:
$ jwebserver
Binding to loopback by default. For all interfaces use "-b 0.0.0.0" or "-b ::".
Serving /usr and subdirectories on 127.0.0.1 port 8000
URL http://127.0.0.1:8000/
⚠️ 默认情况下,服务器会提供当前目录(示例中是 /usr
)的文件服务。我们可以通过 -d
参数指定其他目录:
$ jwebserver -d /opt
Binding to loopback by default. For all interfaces use "-b 0.0.0.0" or "-b ::".
Serving /opt and subdirectories on 127.0.0.1 port 8000
URL http://127.0.0.1:8000/
✅ 注意:必须使用绝对路径。
我们还可以通过 -p
和 -b
参数修改端口和绑定地址:
$ jwebserver -b 0.0.0.0 -p 3003
Serving / and subdirectories on 0.0.0.0 (all interfaces) port 3003
URL http://192.168.1.1:3003/
❌ 踩坑提醒:这种配置会暴露当前目录到整个网络,文件传输前务必确认安全性!
2.2. GET 请求处理
通过浏览器访问指定地址和端口即可使用服务。我们会看到启动目录下的文件和子目录列表:
访问文件时,浏览器会显示内容,同时终端输出日志:
127.0.0.1 - - [09/Feb/2024:12:06:26 +0000] "GET /file.txt HTTP/1.1" 200 -
进入子目录时也会记录相应日志:
127.0.0.1 - - [09/Feb/2024:12:06:52 +0000] "GET /subdirectory/ HTTP/1.1" 200 -
3. API 编程接口
3.1. 定义服务器
用 API 重现命令行功能需要用到 SimpleFileServer
类。该类提供三个核心功能:
- 创建
HttpServer
- 创建
HttpHandler
- 创建
HttpFilter
通过 createFileServer()
快速创建服务器:
public static void main(String[] args) {
InetSocketAddress address = new InetSocketAddress(8080);
Path path = Path.of("/");
HttpServer server = SimpleFileServer.createFileServer(address, path, SimpleFileServer.OutputLevel.VERBOSE);
server.start();
}
关键参数说明:
InetSocketAddress
指定监听地址和端口Path
指定服务目录- 日志级别可按需调整
效果与命令行工具完全一致,可通过 127.0.0.1:8080
访问。
3.2. 请求处理器
要实现更复杂的控制,需要引入 HttpHandler
。通过 createFileHandler()
创建处理器:
HttpHandler handler = SimpleFileServer.createFileHandler(Path.of("/Users"));
server.createContext("/test", handler);
这样所有访问 127.0.0.1:8080/test
的请求都会经过这个处理器。
进阶用法:模拟不同接口的权限控制。用 HttpHandlers.of()
创建响应:
HttpHandler allowedResponse = HttpHandlers.of(200, Headers.of("Allow", "GET"), "Welcome");
HttpHandler deniedResponse = HttpHandlers.of(401, Headers.of("Deny", "GET"), "Denied");
定义路径判断逻辑:
Predicate<Request> findAllowedPath = r -> r.getRequestURI()
.getPath().equals("/test/allowed");
用 handleOrElse()
组装处理器:
HttpHandler handler = HttpHandlers.handleOrElse(findAllowedPath, allowedResponse, deniedResponse);
最终效果:
- 访问
http://127.0.0.1:8080/test/allowed
→ 返回 200 和 "Welcome" - 其他路径 → 返回 401 和 "Denied"
3.3. 过滤器
SimpleFileServer
还支持创建 Filter
来处理日志输出。通过自定义过滤器,我们可以将日志重定向到任意 OutputStream
。
创建过滤器:
Filter filter = SimpleFileServer.createOutputFilter(System.out, SimpleFileServer.OutputLevel.INFO);
✅ 这里用 System.out
演示,实际可替换为日志系统等。
创建服务器时绑定过滤器:
HttpServer server = HttpServer.create(new InetSocketAddress(8080), 10, "/test", handler, filter);
参数解析:
- 监听地址(
InetSocketAddress
) - TCP 连接队列最大长度(10)
- 处理路径(
/test
) - 请求处理器(
handler
) - 日志过滤器(
filter
)
核心优势:完全掌控日志输出流向,比命令行工具更灵活。
4. 总结
本文展示了 Java 18 简易 Web 服务器的核心能力:
✅ **命令行工具 jwebserver
**:
- 秒级启动静态文件服务
- 支持自定义端口、目录和绑定地址
- 适合快速原型和文件共享
✅ 编程接口:
- 通过
SimpleFileServer
实现相同功能 HttpHandler
实现请求路由和权限控制Filter
灵活管理日志输出
适用场景:
- 本地开发测试
- 教学演示
- 简单静态文件服务
- API 原型验证
⚠️ 局限性:不适合生产环境,功能远不如 Tomcat/Jetty 完备。
完整示例代码见 GitHub 仓库。