Прежде чем перейти к этой главе, мы предполагаем, что вы знаете, как написать веб-сервис RESTful на Java. Я покажу вам, как использовать CXF поверх этого JAX-RS (Java API для веб-служб RESTful). Мы создадим веб-сервис, который ведет список последних фильмов. Когда пользователь запрашивает фильм, он указывает идентификатор фильма в своем запросе, сервер найдет фильм и вернет его клиенту. В нашем тривиальном случае мы просто вернем название фильма клиенту, а не фактический двоичный файл MP4. Итак, давайте начнем создавать приложение JAX-RS.
Объявление элемента фильма
Мы объявим корневой элемент XML под названием Movie для хранения идентификатора и имени данного фильма. Элемент объявлен в файле с именем Movie.java. Содержание файла показано здесь —
//Movie.java package com.tutorialspoint.cxf.jaxrs.movie; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(name = "Movie") public class Movie { private long id; private String name; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
Обратите внимание на использование тега XmlRootElement для объявления элемента XML для тега Movie . Далее мы создадим сервис, который хранит список фильмов в своей базе данных.
Создание базы данных сервиса фильмов
Для хранения списка фильмов мы используем предоставляемую Java карту, которая хранит пары ключ-значение. Если список большой, вы будете использовать внешнее хранилище базы данных, которым также будет легче управлять. В нашем тривиальном случае мы будем хранить только пять фильмов в нашей базе данных. Код для класса MovieService приведен ниже —
//MovieService.java package com.tutorialspoint.cxf.jaxrs.movie; import java.util.HashMap; import java.util.Map; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; @Path("/movieservice/") @Produces("text/xml") public class MovieService { long currentId = 123; Map<Long, Movie> movies = new HashMap<>(); public MovieService() { init(); } @GET @Path("/movie/{id}/") public Movie getMovie(@PathParam("id") String id) { long idNumber = Long.parseLong(id); return movies.get(idNumber); } final void init() { Movie c1 = new Movie(); c1.setName("Aquaman"); c1.setId(1001); movies.put(c1.getId(), c1); Movie c2 = new Movie(); c2.setName("Mission Imposssible"); c2.setId(1002); movies.put(c2.getId(), c2); Movie c3 = new Movie(); c3.setName("Black Panther"); c3.setId(1003); movies.put(c3.getId(), c3); Movie c4 = new Movie(); c4.setName("A Star is Born"); c4.setId(1004); movies.put(c4.getId(), c4); Movie c5 = new Movie(); c5.setName("The Meg"); c5.setId(1005); movies.put(c5.getId(), c5); } }
Обратите внимание, что мы используем следующие две аннотации, чтобы указать путь к URL для нашего сервиса фильмов и тип его возврата:
@Path("/movieservice/") @Produces("text/xml")
Мы используем аннотации @GET и @Path, чтобы указать URL-адрес для запроса GET следующим образом:
@GET @Path("/movie/{id}/")
Сама база данных фильма инициализируется в методе init, где мы добавляем пять элементов фильма в базу данных.
Наша следующая задача — написать серверное приложение.
Развивающийся сервер
Для создания сервера мы используем предоставленный CXF класс JAXRSServerFactoryBean .
JAXRSServerFactoryBean factory = new JAXRSServerFactoryBean();
Мы устанавливаем его классы ресурсов, вызывая метод setResourceClasses .
factory.setResourceClasses(Movie.class); factory.setResourceClasses(MovieService.class);
Мы устанавливаем поставщика услуг, вызывая метод setResourceProvider .
factory.setResourceProvider(MovieService.class, new SingletonResourceProvider(new MovieService()));
Мы устанавливаем желаемый адрес публикации , вызывая метод aetAddress —
factory.setAddress("http://localhost:9000/");
Наконец, мы публикуем сервер, вызывая метод create для экземпляра фабрики .
factory.create();
Весь код для серверного приложения приведен ниже —
//Server.java package com.tutorialspoint.cxf.jaxrs.movie; import org.apache.cxf.jaxrs.JAXRSServerFactoryBean; import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider; public class Server { public static void main(String[] args) throws Exception { JAXRSServerFactoryBean factory = new JAXRSServerFactoryBean(); factory.setResourceClasses(Movie.class); factory.setResourceClasses(MovieService.class); factory.setResourceProvider(MovieService.class, new SingletonResourceProvider(new MovieService())); factory.setAddress("http://localhost:9000/"); factory.create(); System.out.println("Server ready..."); Thread.sleep(5 * 60 * 1000); System.out.println("Server exiting ..."); System.exit(0); } }
Финал pom.xml
Здесь мы включили окончательную версию pom.xml ниже —
<?xml version = "1.0" encoding = "UTF-8"?> <project xmlns = "http://maven.apache.org/POM/4.0.0" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.tutorialspoint</groupId> <artifactId>cxf-jaxrs</artifactId> <version>1.0</version> <packaging>jar</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <profiles> <profile> <id>server</id> <build> <defaultGoal>test</defaultGoal> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.6.0</version> <executions> <execution> <phase>test</phase> <goals> <goal>java</goal> </goals> <configuration> <mainClass> com.tutorialspoint.cxf.jaxrs.movie.Server </mainClass> </configuration> </execution> </executions> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http-jetty</artifactId> <version>3.3.0</version> </dependency> </dependencies> </profile> <profile> <id>client</id> <build> <defaultGoal>test</defaultGoal> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <executions> <execution> <phase>test</phase> <goals> <goal>java</goal> </goals> <configuration> <mainClass> com.tutorialspoint.cxf.jaxrs.movie.Client </mainClass> </configuration> </execution> </executions> </plugin> </plugins> </build> </profile> </profiles> <dependencies> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http</artifactId> <version>3.3.0</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http-jetty</artifactId> <version>3.3.0</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxrs</artifactId> <version>3.3.0</version> </dependency> <dependency> <groupId>jakarta.ws.rs</groupId> <artifactId>jakarta.ws.rs-api</artifactId> <version>2.1.5</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.7</version> </dependency> </dependencies> </project>
Развивающийся клиент
Написание RS-клиента тривиально. Мы просто создаем объект URL и открываем его поток. Мы используем предоставленный CXF класс IOUtils для копирования содержимого входного потока в локальный поток.
URL url = new URL("http://localhost:9000/movieservice/movie/1002"); try (InputStream instream = url.openStream(); CachedOutputStream outstream = new CachedOutputStream()) { IOUtils.copy(instream, outstream); }
Весь код для клиентского приложения приведен ниже —
//Client.java package com.tutorialspoint.cxf.jaxrs.movie; import java.io.InputStream; import java.net.URL; import org.apache.cxf.helpers.IOUtils; import org.apache.cxf.io.CachedOutputStream; public class Client { public static void main(String[] args) throws Exception { URL url = new URL("http://localhost:9000/movieservice/movie/1002"); try (InputStream instream = url.openStream(); CachedOutputStream outstream = new CachedOutputStream()) { IOUtils.copy(instream, outstream); String str = outstream.getOut().toString(); System.out.println(str); } } }
Тестирование приложения JAX-RS
Запустите сервер, используя следующую команду в окне командной строки:
mvn -Pserver
Теперь на консоли вы увидите следующее сообщение:
INFO: Setting the server's publish address to be http://localhost:9000
Теперь откройте браузер и введите следующий URL —
http://localhost:9000/movieservice/movie/1002
Вы увидите следующее в окне браузера.
Вы можете вызвать службу, используя клиентское приложение Java, которое мы разработали, выполнив следующую команду в отдельном окне командной строки.
mvn -Pclient
Вы увидите следующий вывод —
<?xml version="1.0" encoding = "UTF-8" standalone="yes"?> <Movie><id>1002</id><name>Mission Imposssible</name></Movie>
Примеры CXF предоставляют несколько примеров того, как использовать CXF с JAX-RS. Заинтересованным читателям предлагается изучить эти образцы.