1. 概述
随着微服务架构和云原生应用的普及,开发者对轻量、快速启动的应用服务器需求日益增长。
本文将带你快速入门 Open Liberty 框架,学会如何创建和消费一个 RESTful 接口。我们还会介绍它的一些核心特性,帮助你在实际项目中快速上手。
2. Open Liberty 简介
Open Liberty 是 一个面向 Java 生态的开源框架,支持基于 Eclipse MicroProfile 和 Jakarta EE 构建微服务。
它是一个灵活、轻量且启动迅速的 Java 运行时,非常适合云原生微服务开发。
✅ 核心优势:
- 按需启用功能模块,只加载应用所需特性,显著降低内存占用
- 支持 Docker、Kubernetes 等主流容器平台部署
- 开发模式支持热加载,代码修改后自动生效,无需重启
这种“按需组装”的设计,让应用更轻、启动更快,是构建现代微服务的理想选择。
3. 构建与运行
我们先创建一个名为 open-liberty
的 Maven 项目,然后在 pom.xml
中引入 liberty-maven-plugin
插件:
<plugin>
<groupId>io.openliberty.tools</groupId>
<artifactId>liberty-maven-plugin</artifactId>
<version>3.3-M3</version>
</plugin>
或者,你也可以选择使用 openliberty-runtime
依赖替代插件:
<dependency>
<groupId>io.openliberty</groupId>
<artifactId>openliberty-runtime</artifactId>
<version>20.0.0.1</version>
<type>zip</type>
</dependency>
Gradle 用户可以在 build.gradle
中添加:
dependencies {
libertyRuntime group: 'io.openliberty', name: 'openliberty-runtime', version: '20.0.0.1'
}
接着,引入 Jakarta EE Web API 和 MicroProfile 依赖:
<dependency>
<groupId>jakarta.platform</groupId>
<artifactId>jakarta.jakartaee-web-api</artifactId>
<version>8.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.microprofile</groupId>
<artifactId>microprofile</artifactId>
<version>3.2</version>
<type>pom</type>
<scope>provided</scope>
</dependency>
配置默认端口:
<properties>
<liberty.var.default.http.port>9080</liberty.var.default.http.port>
<liberty.var.default.https.port>9443</liberty.var.default.https.port>
</properties>
在 src/main/liberty/config
目录下创建 server.xml
:
<server description="Baeldung Open Liberty server">
<featureManager>
<feature>mpHealth-2.0</feature>
</featureManager>
<webApplication location="open-liberty.war" contextRoot="/" />
<httpEndpoint host="*" httpPort="${default.http.port}"
httpsPort="${default.https.port}" id="defaultHttpEndpoint" />
</server>
⚠️ 注意:mpHealth-2.0
是 MicroProfile Health 功能,用于健康检查。
完成配置后,执行编译:
mvn clean package
启动开发服务器:
mvn liberty:dev
✅ 应用启动成功,访问 http://localhost:9080 可看到默认页面:
健康检查接口:http://localhost:9080/health
{"checks":[],"status":"UP"}
💡 liberty:dev
命令会以开发模式启动,支持热加载。生产环境建议使用 liberty:run
。
其他常用命令:
liberty:start-server
:后台启动liberty:stop-server
:停止服务器
4. Servlet 使用
要在项目中使用 Servlet,需在 server.xml
中启用 servlet-4.0
功能:
<featureManager>
...
<feature>servlet-4.0</feature>
</featureManager>
如果使用 openliberty-runtime
依赖,还需添加 Maven 依赖:
<dependency>
<groupId>io.openliberty.features</groupId>
<artifactId>servlet-4.0</artifactId>
<version>20.0.0.1</version>
<type>esa</type>
</dependency>
⚠️ 使用 liberty-maven-plugin
则无需此依赖。
创建 AppServlet
:
@WebServlet(urlPatterns="/app")
public class AppServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String htmlOutput = "<html><h2>Hello! Welcome to Open Liberty</h2></html>";
response.getWriter().append(htmlOutput);
}
}
✅ @WebServlet
注解将 Servlet 映射到 /app
路径。
访问 http://localhost:9080/app 查看效果:
5. 创建 RESTful 接口
首先在 server.xml
中启用 JAX-RS 功能:
<featureManager>
...
<feature>jaxrs-2.1</feature>
</featureManager>
创建 ApiApplication
类定义接口根路径:
@ApplicationPath("/api")
public class ApiApplication extends Application {
}
定义 Person
模型类:
public class Person {
private String username;
private String email;
// getters and setters
// constructors
}
创建 PersonResource
接口类:
@RequestScoped
@Path("persons")
public class PersonResource {
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<Person> getAllPersons() {
return Arrays.asList(new Person(1, "normanlewis", "norman@example.com"));
}
}
✅ 此接口可通过 http://localhost:9080/api/persons
访问。
使用 curl 测试:
curl --request GET --url http://localhost:9080/api/persons
响应:
[{"id":1, "username":"normanlewis", "email":"norman@example.com"}]
添加 POST 接口:
@POST
@Consumes(MediaType.APPLICATION_JSON)
public Response addPerson(Person person) {
String respMessage = "Person " + person.getUsername() + " received successfully.";
return Response.status(Response.Status.CREATED).entity(respMessage).build();
}
调用 POST 接口:
curl --request POST --url http://localhost:9080/api/persons \
--header 'content-type: application/json' \
--data '{"username": "normanlewis", "email": "norman@example.com"}'
响应:
Person normanlewis received successfully.
6. 持久化支持
6.1 配置
为接口添加数据库支持。
添加 Derby 依赖:
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
<version>10.14.2.0</version>
</dependency>
在 server.xml
中启用 JPA、JSON-P 和 CDI 功能:
<featureManager>
...
<feature>jpa-2.2</feature>
<feature>jsonp-1.1</feature>
<feature>cdi-2.0</feature>
</featureManager>
创建 persistence.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.2"
xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd">
<persistence-unit name="jpa-unit" transaction-type="JTA">
<jta-data-source>jdbc/jpadatasource</jta-data-source>
<properties>
<property name="eclipselink.ddl-generation" value="create-tables"/>
<property name="eclipselink.ddl-generation.output-mode" value="both" />
</properties>
</persistence-unit>
</persistence>
配置数据源:
<library id="derbyJDBCLib">
<fileset dir="${shared.resource.dir}" includes="derby*.jar"/>
</library>
<dataSource id="jpadatasource" jndiName="jdbc/jpadatasource">
<jdbcDriver libraryRef="derbyJDBCLib" />
<properties.derby.embedded databaseName="libertyDB" createDatabase="create" />
</dataSource>
⚠️ 注意 jndiName
需与 persistence.xml
中的 jta-data-source
一致。
6.2 实体与 DAO
改造 Person
类为 JPA 实体:
@Entity
public class Person {
@GeneratedValue(strategy = GenerationType.AUTO)
@Id
private int id;
private String username;
private String email;
// getters and setters
}
创建 PersonDao
:
@RequestScoped
public class PersonDao {
@PersistenceContext(name = "jpa-unit")
private EntityManager em;
public Person createPerson(Person person) {
em.persist(person);
return person;
}
public Person readPerson(int personId) {
return em.find(Person.class, personId);
}
}
在 PersonResource
中注入 DAO:
@RequestScoped
@Path("persons")
public class PersonResource {
@Inject
private PersonDao personDao;
// ...
}
更新 addPerson
方法实现持久化:
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Transactional
public Response addPerson(Person person) {
personDao.createPerson(person);
String respMessage = "Person #" + person.getId() + " created successfully.";
return Response.status(Response.Status.CREATED).entity(respMessage).build();
}
测试 POST 请求:
curl --request POST --url http://localhost:9080/api/persons \
--header 'content-type: application/json' \
--data '{"username": "normanlewis", "email": "norman@example.com"}'
响应:
Person #1 created successfully.
添加 GET 单个资源接口:
@GET
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
@Transactional
public Person getPerson(@PathParam("id") int id) {
Person person = personDao.readPerson(id);
return person;
}
测试:
curl --request GET --url http://localhost:9080/api/persons/1
响应:
{"email":"norman@example.com","id":1,"username":"normanlewis"}
7. 使用 JSON-B 消费 REST 接口
启用 JSON-B 功能:
<featureManager>
...
<feature>jsonb-1.0</feature>
</featureManager>
创建 RestConsumer
:
public class RestConsumer {
public static String consumeWithJsonb(String targetUrl) {
Client client = ClientBuilder.newClient();
Response response = client.target(targetUrl).request().get();
String result = response.readEntity(String.class);
response.close();
client.close();
return result;
}
}
编写测试用例:
@Test
public void whenConsumeWithJsonb_thenGetPerson() {
String url = "http://localhost:9080/api/persons/1";
String result = RestConsumer.consumeWithJsonb(url);
Person person = JsonbBuilder.create().fromJson(result, Person.class);
assertEquals(1, person.getId());
assertEquals("normanlewis", person.getUsername());
assertEquals("norman@example.com", person.getEmail());
}
💡 提示:你也可以使用 MicroProfile Rest Client(添加 mpRestClient-1.3
功能),它提供了更优雅的声明式 REST 调用方式。
8. 总结
本文介绍了 Open Liberty —— 一个轻量、高性能的 Java 运行时,完整支持 Eclipse MicroProfile 和 Jakarta EE 特性。
我们完成了以下实践:
- ✅ 使用 JAX-RS 构建 RESTful 接口
- ✅ 集成 JPA + CDI 实现数据持久化
- ✅ 使用 JSON-B 消费外部接口
Open Liberty 的模块化设计和开发友好性,让它成为构建云原生微服务的有力工具。
所有示例代码已上传至 GitHub:https://github.com/eugenp/tutorials/tree/master/microservices-modules/open-liberty