Apache CXF avec JAX-RS

Avant de poursuivre dans ce chapitre, nous supposons que vous savez comment écrire un service Web RESTful en Java. Je vais vous montrer comment utiliser CXF en plus de ce JAX-RS (API Java pour les services Web RESTful). Nous allons créer un service Web qui maintient une liste des derniers films. Lorsque l'utilisateur demande un film, il spécifie l'ID du film dans sa demande, le serveur localisera le film et le retournera au client. Dans notre cas trivial, nous retournerons simplement le nom du film au client et non le fichier MP4 binaire réel. Commençons donc par créer une application JAX-RS.

Déclaration d'un élément de film

Nous déclarerons un élément racine XML appelé Movie pour stocker l'id et le nom d'un film donné. L'élément est déclaré dans un fichier appelé Movie.java. Le contenu du fichier est affiché ici -

//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;
   }
}

Notez l'utilisation de XmlRootElement pour déclarer l'élément XML pour le Moviemarque. Ensuite, nous allons créer un service qui contient la liste des films dans sa base de données.

Création de la base de données Movie Service

Pour stocker la liste des films, nous utilisons Java fourni Mapqui stocke les paires clé-valeur. Si la liste est longue, vous utiliserez un stockage de base de données externe qui sera également plus facile à gérer. Dans notre cas trivial, nous ne stockerons que cinq films dans notre base de données. Le code de la classe MovieService est donné ci-dessous -

//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);
   }
}

Notez que nous utilisons les deux annotations suivantes pour spécifier le chemin d'URL de notre service de film et son type de retour -

@Path("/movieservice/")
@Produces("text/xml")

Nous utilisons les annotations @GET et @Path pour spécifier l'URL de la requête GET comme suit -

@GET
@Path("/movie/{id}/")

La base de données de films elle-même est initialisée dans la méthode init, où nous ajoutons cinq éléments de film à la base de données.

Notre prochaine tâche est d'écrire une application serveur.

Développement du serveur

Pour créer un serveur, nous utilisons CXF fourni JAXRSServerFactoryBean classe.

JAXRSServerFactoryBean factory = new JAXRSServerFactoryBean();

Nous définissons ses classes de ressources en appelant le setResourceClasses méthode.

factory.setResourceClasses(Movie.class);
factory.setResourceClasses(MovieService.class);

Nous définissons le fournisseur de services en appelant le setResourceProvider méthode.

factory.setResourceProvider(MovieService.class,
new SingletonResourceProvider(new MovieService()));

Nous définissons le publish adresse en appelant le aetAddress méthode -

factory.setAddress("http://localhost:9000/");

Enfin, nous publions le serveur en appelant la méthode create sur le factory exemple.

factory.create();

Le code complet de l'application serveur est donné ci-dessous -

//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);
   }
}

Le pom.xml final

Ici, nous avons inclus la version finale de pom.xml ci-dessous -

<?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>

Client en développement

L'écriture du client RS est triviale. Nous créons simplement un objet URL et ouvrons son flux. Nous utilisons la classe IOUtils fournie par CXF pour copier le contenu du flux d'entrée dans un flux local.

URL url = new URL("http://localhost:9000/movieservice/movie/1002");
try (InputStream instream = url.openStream();
CachedOutputStream outstream = new CachedOutputStream()) {
   IOUtils.copy(instream, outstream);
}

Le code complet de l'application client est donné ci-dessous -

//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);
      }
   }
}

Test de l'application JAX-RS

Exécutez le serveur en utilisant la commande suivante dans la fenêtre de ligne de commande -

mvn -Pserver

Maintenant, vous verrez le message suivant sur la console -

INFO: Setting the server's publish address to be http://localhost:9000

Maintenant, ouvrez votre navigateur et tapez l'URL suivante -

http://localhost:9000/movieservice/movie/1002

Vous verrez ce qui suit dans la fenêtre du navigateur.

Vous pouvez appeler le service en utilisant une application client Java que nous avons développée en exécutant la commande suivante dans une fenêtre de ligne de commande distincte.

mvn -Pclient

Vous verrez la sortie suivante -

<?xml version="1.0" encoding = "UTF-8" standalone="yes"?>
<Movie><id>1002</id><name>Mission Imposssible</name></Movie>

Les exemples CXF fournissent plusieurs exemples d'utilisation de CXF avec JAX-RS. Les lecteurs intéressés sont encouragés à étudier ces échantillons.