«1. Обзор
С ростом популярности микросервисной архитектуры и разработки облачных приложений растет потребность в быстром и легком сервере приложений.
В этом вводном руководстве мы рассмотрим платформу Open Liberty для создания и использования веб-службы RESTful. Мы также рассмотрим несколько основных функций, которые он предоставляет.
2. Open Liberty
Open Liberty — это открытая среда для экосистемы Java, позволяющая разрабатывать микросервисы с использованием функций платформ Eclipse MicroProfile и Jakarta EE.
Это гибкая, быстрая и легкая среда выполнения Java, которая кажется многообещающей для разработки облачных микросервисов.
Фреймворк позволяет нам настраивать только те функции, которые нужны нашему приложению, что приводит к меньшему объему памяти при запуске. Кроме того, его можно развернуть на любой облачной платформе с использованием таких контейнеров, как Docker и Kubernetes.
Он поддерживает быструю разработку за счет перезагрузки кода в реальном времени для быстрой итерации.
3. Сборка и запуск
Сначала мы создадим простой проект на основе Maven с именем open-liberty, а затем добавим в pom.xml новейший подключаемый модуль Liberty-maven-plugin:
<plugin>
<groupId>io.openliberty.tools</groupId>
<artifactId>liberty-maven-plugin</artifactId>
<version>3.3-M3</version>
</plugin>
Или мы можем добавить последнюю зависимость Maven openliberty-runtime в качестве альтернативы Liberty-maven-plugin:
<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.jakartaee-web-api и микропрофиля Maven:
<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>
Затем давайте добавим свойства порта HTTP по умолчанию в pom.xml:
<properties>
<liberty.var.default.http.port>9080</liberty.var.default.http.port>
<liberty.var.default.https.port>9443</liberty.var.default.https.port>
</properties>
Затем мы создадим файл server.xml в каталоге src/main/liberty/config:
<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 для проверки работоспособности приложения.
Вот и все основные настройки. Давайте запустим команду Maven для первой компиляции файлов:
mvn clean package
Наконец, давайте запустим сервер с помощью предоставленной Liberty команды Maven:
mvn liberty:dev
Вуаля! Наше приложение запущено и будет доступно по адресу localhost:9080:
Кроме того, мы можем получить доступ к состоянию приложения по адресу localhost:9080/health:
{"checks":[],"status":"UP"}
Команда Liberty:dev запускает сервер Open Liberty в режим разработки, который перезагружает любые изменения, внесенные в код или конфигурацию, без перезапуска сервера.
Точно так же доступна команда Liberty:run для запуска сервера в производственном режиме.
Кроме того, мы можем использовать Liberty:Start-Server и Liberty:Stop-Server для запуска/остановки сервера в фоновом режиме.
4. Сервлет
Чтобы использовать сервлеты в приложении, мы добавим функцию servlet-4.0 в server.xml:
<featureManager>
...
<feature>servlet-4.0</feature>
</featureManager>
Добавьте последнюю зависимость servlet-4.0 Maven, если используете openliberty- Зависимость Maven во время выполнения в pom.xml:
<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, расширяющий класс HttpServlet:
@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, которая сделает AppServlet доступным по указанному шаблону URL.
Давайте получим доступ к сервлету по адресу localhost:9080/app:
5. Создайте веб-службу RESTful
Сначала добавим функцию jaxrs-2.1 в server.xml:
~~ ~ Затем мы создадим класс ApiApplication, который предоставляет конечные точки веб-службе RESTful:
<featureManager>
...
<feature>jaxrs-2.1</feature>
</featureManager>
Здесь мы использовали аннотацию @ApplicationPath для URL-пути.
@ApplicationPath("/api")
public class ApiApplication extends Application {
}
Затем давайте создадим класс Person, обслуживающий модель:
Затем мы создадим класс PersonResource для определения сопоставлений HTTP:
public class Person {
private String username;
private String email;
// getters and setters
// constructors
}
Здесь мы добавили getAllPersons метод сопоставления GET с конечной точкой /api/persons. Итак, веб-служба RESTful готова, и команда Liberty:dev будет загружать изменения «на лету».
@RequestScoped
@Path("persons")
public class PersonResource {
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<Person> getAllPersons() {
return Arrays.asList(new Person(1, "normanlewis", "[email protected]"));
}
}
Давайте получим доступ к веб-сервису /api/persons RESTful с помощью запроса curl GET:
Затем мы получим в ответ массив JSON:
curl --request GET --url http://localhost:9080/api/persons
Аналогичным образом мы можем добавить POST сопоставление путем создания метода addPerson:
[{"id":1, "username":"normanlewis", "email":"[email protected]"}]
Теперь мы можем вызвать конечную точку с помощью POST-запроса curl:
@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();
}
Ответ будет выглядеть так:
curl --request POST --url http://localhost:9080/api/persons \
--header 'content-type: application/json' \
--data '{"username": "normanlewis", "email": "[email protected]"}'
6. Постоянство
Person normanlewis received successfully.
«6.1. Конфигурация
Давайте добавим поддержку постоянства в наши веб-сервисы RESTful.
Сначала мы добавим зависимость derby Maven к pom.xml:
Затем мы добавим на сервер несколько функций, таких как jpa-2.2, jsonp-1.1 и cdi-2.0. .xml:
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
<version>10.14.2.0</version>
</dependency>
Здесь функция jsonp-1.1 предоставляет API Java для обработки JSON, а функция cdi-2.0 обрабатывает области действия и внедрение зависимостей.
<featureManager>
...
<feature>jpa-2.2</feature>
<feature>jsonp-1.1</feature>
<feature>cdi-2.0</feature>
</featureManager>
Далее мы создадим файл persistence.xml в каталоге src/main/resources/META-INF:
Здесь мы использовали генерацию EclipseLink DDL для автоматического создания схемы нашей базы данных. Мы также можем использовать другие альтернативы, такие как Hibernate.
<?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>
Затем добавим конфигурацию dataSource в server.xml:
Обратите внимание, jndiName имеет ту же ссылку на тег jta-data-source в файле persistence.xml.
<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>
6.2. Entity и DAO
Затем мы добавим аннотацию @Entity и идентификатор в наш класс Person:
Далее давайте создадим класс PersonDao, который будет взаимодействовать с базой данных, используя экземпляр EntityManager: ~~ ~
@Entity
public class Person {
@GeneratedValue(strategy = GenerationType.AUTO)
@Id
private int id;
private String username;
private String email;
// getters and setters
}
Обратите внимание, что @PersistenceContext определяет ту же ссылку на тег persistence-unit в файле persistence.xml.
@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);
}
}
Теперь мы добавим зависимость PersonDao в класс PersonResource:
Здесь мы использовали аннотацию @Inject, предоставленную функцией CDI.
@RequestScoped
@Path("person")
public class PersonResource {
@Inject
private PersonDao personDao;
// ...
}
Наконец, мы обновим метод addPerson класса PersonResource, чтобы сохранить объект Person:
Здесь метод addPerson снабжен аннотацией @Transactional для управления транзакциями управляемых компонентов CDI.
@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:
Затем мы получим текстовый ответ:
curl --request POST --url http://localhost:9080/api/persons \
--header 'content-type: application/json' \
--data '{"username": "normanlewis", "email": "[email protected]"}'
Аналогичным образом добавим метод getPerson с отображением GET для получения Объект Person:
Person #1 created successfully.
Давайте вызовем конечную точку с помощью запроса curl GET:
@GET
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
@Transactional
public Person getPerson(@PathParam("id") int id) {
Person person = personDao.readPerson(id);
return person;
}
Затем мы получим объект Person в виде ответа JSON:
curl --request GET --url http://localhost:9080/api/persons/1
7. Использование веб-службы RESTful Использование JSON-B
{"email":"[email protected]","id":1,"username":"normanlewis"}
Во-первых, мы обеспечим возможность прямой сериализации и десериализации моделей, добавив функцию jsonb-1.0 в server.xml: method:
Здесь мы использовали класс ClientBuilder для запроса конечных точек веб-службы RESTful.
<featureManager>
...
<feature>jsonb-1.0</feature>
</featureManager>
Наконец, давайте напишем модульный тест для использования веб-службы RESTful /api/person и проверки ответа:
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;
}
}
Здесь мы использовали класс JsonbBuilder для анализа ответа String в объекте Person.
Кроме того, мы можем использовать клиент MicroProfile Rest Client, добавив функцию mpRestClient-1.3 для использования веб-сервисов RESTful. Он предоставляет интерфейс RestClientBuilder для запроса конечных точек веб-службы RESTful.
@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("[email protected]", person.getEmail());
}
8. Заключение
В этой статье мы рассмотрели инфраструктуру Open Liberty — быструю и легкую среду выполнения Java, которая предоставляет все функции платформ Eclipse MicroProfile и Jakarta EE.
Для начала мы создали веб-сервис RESTful с использованием JAX-RS. Затем мы включили постоянство, используя такие функции, как JPA и CDI.
Наконец, мы использовали веб-службу RESTful с использованием JSON-B.
Как обычно, все реализации кода доступны на GitHub.
«
As usual, all the code implementations are available over on GitHub.