1. 概述
Helidon 是 Oracle 最近开源的一款用于构建 Java 微服务的轻量级框架,此前主要用于 Oracle 内部的 J4C(Java for Cloud)项目。
本篇文章将带你了解 Helidon 的核心概念,并通过示例演示如何使用 Helidon 构建并运行一个微服务应用。
2. 编程模型
目前,Helidon 提供了两种微服务编程模型:
✅ Helidon SE:基于反应式编程模型的轻量级微框架
✅ Helidon MP:基于 Eclipse MicroProfile 的运行时,兼容 Jakarta EE 社区标准
⚠️ 无论使用哪种模型,Helidon 微服务本质上都是一个 Java SE 应用程序,它通过 main
方法启动一个轻量级 HTTP 服务器。
3. Helidon SE
Helidon SE 的核心组件包括:WebServer、Config、Security。
3.1. 配置 WebServer
首先,我们需要在 pom.xml
中添加 Helidon WebServer 的依赖:
<dependency>
<groupId>io.helidon.webserver</groupId>
<artifactId>helidon-webserver</artifactId>
<version>3.2.2</version>
</dependency>
要创建一个简单的 Web 应用,可以使用以下方式之一:
WebServer.create(routing, serverConfig)
WebServer.create(routing)
(使用默认配置,随机端口)
示例:一个监听在 9001 端口的 Web 服务,处理 /greet
路径的 GET 请求:
public static void main(String... args) throws Exception {
Routing routing = Routing.builder()
.get("/greet", (request, response) -> response.send("Hello World !")).build();
WebServer.builder(routing)
.port(9001).addRouting(routing).build()
.start()
.thenAccept(ws ->
System.out.println("Server started at: http://localhost:" + ws.port())
);
}
⚠️ 如果直接运行上述代码,会报错:
Exception in thread "main" java.lang.IllegalStateException:
No implementation found for SPI: io.helidon.webserver.spi.WebServerFactory
这是因为 WebServer
是一个 SPI 接口,需要提供具体实现。Helidon 默认使用基于 Netty 的实现:
<dependency>
<groupId>io.helidon.webserver</groupId>
<artifactId>helidon-webserver-netty</artifactId>
<version>0.10.6</version>
<scope>runtime</scope>
</dependency>
✅ 添加依赖后就可以启动服务,并通过以下 URL 测试:
http://localhost:9001/greet
3.2. Config API
Config
API 用于读取配置数据,支持多种配置源。默认配置文件为 application.properties
,位于 classpath 下。
添加依赖:
<dependency>
<groupId>io.helidon.config</groupId>
<artifactId>helidon-config</artifactId>
<version>3.2.2</version>
</dependency>
读取配置:
Config config = Config.builder().build();
示例配置文件 application.properties
:
server.port=9080
web.debug=true
web.page-size=15
user.home=C:/Users/app
获取配置值:
int port = config.get("server.port").asInt().get();
int pageSize = config.get("web.page-size").asInt().get();
boolean debug = config.get("web.debug").asBoolean().get();
String userHome = config.get("user.home").asString().get();
✅ 支持的配置文件格式(优先级顺序):
application.yaml
application.conf
application.json
application.properties
如需使用 YAML 格式,添加依赖:
<dependency>
<groupId>io.helidon.config</groupId>
<artifactId>helidon-config-yaml</artifactId>
<version>3.2.2</version>
</dependency>
示例 application.yml
:
server:
port: 9080
web:
debug: true
page-size: 15
user:
home: C:/Users/app
✅ 可通过环境变量或系统属性覆盖配置项。
也可以自定义配置源,例如从 Git 或 etcd 加载配置。
3.3. Routing API
Routing API 用于将 HTTP 请求映射到 Java 方法。
✅ 简单路由:
Routing routing = Routing.builder()
.get("/path", (request, response) -> {} );
✅ 使用 RequestPredicate
添加更多匹配条件:
Routing routing = Routing.builder()
.post("/save",
RequestPredicate.whenRequest()
.containsHeader("header1")
.containsCookie("cookie1")
.accepts(MediaType.APPLICATION_JSON)
.containsQueryParameter("param1")
.hasContentType("application/json")
.thenApply((request, response) -> { })
.otherwise((request, response) -> { }))
.build();
✅ 使用 Service
类实现 REST 接口:
public class BookResource implements Service {
private BookManager bookManager = new BookManager();
@Override
public void update(Routing.Rules rules) {
rules
.get("/", this::books)
.get("/{id}", this::bookById);
}
private void bookById(ServerRequest serverRequest, ServerResponse serverResponse) {
String id = serverRequest.path().param("id");
Book book = bookManager.get(id);
JsonObject jsonObject = from(book);
serverResponse.send(jsonObject);
}
private void books(ServerRequest serverRequest, ServerResponse serverResponse) {
List<Book> books = bookManager.getAll();
JsonArray jsonArray = from(books);
serverResponse.send(jsonArray);
}
}
✅ 添加 JSON 支持依赖:
<dependency>
<groupId>io.helidon.webserver</groupId>
<artifactId>helidon-webserver-json</artifactId>
<version>0.11.0</version>
</dependency>
注册路由:
Routing routing = Routing.builder()
.register(JsonSupport.get())
.register("/books", new BookResource())
.build();
访问接口:
http://localhost:9080/books
http://localhost:9080/books/0001-201810
3.4. 安全模块 Security
✅ 添加依赖:
<dependency>
<groupId>io.helidon.security</groupId>
<artifactId>helidon-security</artifactId>
<version>3.2.2</version>
</dependency>
<dependency>
<groupId>io.helidon.security.providers</groupId>
<artifactId>helidon-security-providers-http-auth</artifactId>
<version>3.2.2</version>
</dependency>
<dependency>
<groupId>io.helidon.security.integration</groupId>
<artifactId>helidon-security-integration-webserver</artifactId>
<version>3.2.2</version>
</dependency>
✅ 简单配置方式:
Map<String, MyUser> users = //...
SecureUserStore store = user -> Optional.ofNullable(users.get(user));
HttpBasicAuthProvider httpBasicAuthProvider = HttpBasicAuthProvider.builder()
.realm("myRealm")
.subjectType(SubjectType.USER)
.userStore(store)
.build();
Security security = Security.builder()
.addAuthenticationProvider(httpBasicAuthProvider)
.build();
✅ 或通过 application.yml
配置:
security:
providers:
- http-basic-auth:
realm: "helidon"
principal-type: USER
users:
- login: "user"
password: "user"
roles: ["ROLE_USER"]
- login: "admin"
password: "admin"
roles: ["ROLE_USER", "ROLE_ADMIN"]
web-server:
securityDefaults:
authenticate: true
paths:
- path: "/user"
methods: ["get"]
roles-allowed: ["ROLE_USER", "ROLE_ADMIN"]
- path: "/admin"
methods: ["get"]
roles-allowed: ["ROLE_ADMIN"]
加载配置并注册安全模块:
Config config = Config.create();
Security security = Security.fromConfig(config);
Routing routing = Routing.builder()
.register(WebSecurity.create(config))
.get("/user", (request, response) -> response.send("Hello, I'm Helidon SE"))
.get("/admin", (request, response) -> response.send("Hello, I'm Helidon SE"))
.build();
4. Helidon MP
✅ Helidon MP 是 Eclipse MicroProfile 的实现,可用于运行任何兼容 MicroProfile 的微服务。
添加依赖:
<dependency>
<groupId>io.helidon.microprofile.bundles</groupId>
<artifactId>helidon-microprofile</artifactId>
<version>3.2.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-binding</artifactId>
<version>3.1.2</version>
</dependency>
✅ 添加 beans.xml
文件:
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd"
version="2.0" bean-discovery-mode="annotated">
</beans>
✅ 启动服务:
public static void main(String... args) {
Server server = Server.builder()
.addApplication(LibraryApplication.class)
.port(9080)
.build();
server.start();
}
5. 总结
本文介绍了 Helidon 的主要组件,展示了如何使用 Helidon SE 和 MP 构建微服务。Helidon MP 作为 Eclipse MicroProfile 的运行时,兼容性良好,可运行现有 MicroProfile 微服务。
✅ 示例代码可在 GitHub 获取。