Apache CXF mit JAX-RS

Bevor Sie mit diesem Kapitel fortfahren, gehen wir davon aus, dass Sie wissen, wie man einen RESTful-Webdienst in Java schreibt. Ich werde Ihnen zeigen, wie Sie CXF zusätzlich zu diesem JAX-RS (Java-API für RESTful Web Services) verwenden. Wir werden einen Webdienst erstellen, der eine Liste der neuesten Filme enthält. Wenn der Benutzer einen Film anfordert, gibt er die Film-ID in seiner Anfrage an. Der Server sucht den Film und gibt ihn an den Client zurück. In unserem trivialen Fall geben wir einfach den Filmnamen an den Client zurück und nicht die eigentliche binäre MP4-Datei. Beginnen wir also mit der Erstellung einer JAX-RS-Anwendung.

Filmelement deklarieren

Wir deklarieren ein XML-Stammelement namens Movie zum Speichern der ID und des Namens für einen bestimmten Film. Das Element wird in einer Datei namens Movie.java deklariert. Der Inhalt der Datei wird hier angezeigt -

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

Beachten Sie die Verwendung von XmlRootElement Tag, um das XML-Element für das zu deklarieren MovieEtikett. Als Nächstes erstellen wir einen Dienst, der die Liste der Filme in seiner Datenbank enthält.

Erstellen einer Movie Service-Datenbank

Zum Speichern der Liste der Filme verwenden wir Java Mapdas speichert die Schlüssel-Wert-Paare. Wenn die Liste groß ist, verwenden Sie einen externen Datenbankspeicher, der auch einfacher zu verwalten ist. In unserem trivialen Fall speichern wir nur fünf Filme in unserer Datenbank. Der Code für die MovieService-Klasse ist unten angegeben -

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

Beachten Sie, dass wir die folgenden zwei Anmerkungen verwenden, um den URL-Pfad für unseren Filmdienst und dessen Rückgabetyp anzugeben:

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

Wir verwenden die Annotationen @GET und @Path, um die URL für die GET-Anforderung wie folgt anzugeben:

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

Die Filmdatenbank selbst wird mit der init-Methode initialisiert, bei der der Datenbank fünf Filmelemente hinzugefügt werden.

Unsere nächste Aufgabe ist das Schreiben einer Serveranwendung.

Server entwickeln

Um einen Server zu erstellen, verwenden wir das mitgelieferte CXF JAXRSServerFactoryBean Klasse.

JAXRSServerFactoryBean factory = new JAXRSServerFactoryBean();

Wir setzen seine Ressourcenklassen durch Aufrufen von setResourceClasses Methode.

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

Wir stellen den Dienstanbieter ein, indem wir die anrufen setResourceProvider Methode.

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

Wir stellen das Gewünschte ein publish Adresse durch Anrufen der aetAddress Methode -

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

Schließlich veröffentlichen wir den Server, indem wir die create-Methode auf dem aufrufen factory Beispiel.

factory.create();

Der gesamte Code für die Serveranwendung ist unten angegeben -

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

Die endgültige pom.xml

Hier haben wir die endgültige Version von pom.xml unten aufgenommen -

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

Das Schreiben des RS-Clients ist trivial. Wir erstellen einfach ein URL-Objekt und öffnen seinen Stream. Wir verwenden die von CXF bereitgestellte IOUtils-Klasse, um den Inhalt des Eingabestreams in einen lokalen Stream zu kopieren.

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

Der gesamte Code für die Client-Anwendung ist unten angegeben -

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

Testen der JAX-RS-Anwendung

Führen Sie den Server mit dem folgenden Befehl im Befehlszeilenfenster aus:

mvn -Pserver

Jetzt wird die folgende Meldung auf der Konsole angezeigt:

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

Öffnen Sie nun Ihren Browser und geben Sie die folgende URL ein:

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

Im Browserfenster sehen Sie Folgendes.

Sie können den Dienst mithilfe einer Java-Clientanwendung aufrufen, die wir entwickelt haben, indem Sie den folgenden Befehl in einem separaten Befehlszeilenfenster ausführen.

mvn -Pclient

Sie sehen die folgende Ausgabe -

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

CXF-Beispiele enthalten mehrere Beispiele für die Verwendung von CXF mit JAX-RS. Die interessierten Leser werden aufgefordert, diese Proben zu studieren.