Apache CXF - Guida rapida
Nell'ambiente di oggi, è possibile creare un'applicazione di servizio Web utilizzando diverse opzioni. È possibile utilizzare uno o più dei numerosi protocolli standard e ampiamente accettati per la comunicazione. Ad esempio SOAP , XML / HTTP, RESTful HTTP e CORBA (Common Object Request Broker Architecture, che era molto popolare nei tempi antichi ma non così frequentemente utilizzata ora.
Hai anche una scelta di diversi trasporti come HTTP, JMS , JBI e la scelta di API front-end come JAX-RS e JAX-WS . Avendo così tante opzioni per lo sviluppo di servizi web, è necessario un framework di servizi open source per incollare tutte le opzioni sopra menzionate insieme e questo è ciò che fa Apache CXF .
In questo tutorial imparerai come utilizzare CXF per creare sia un servizio web che un client che utilizza il servizio, utilizzando una o più delle opzioni che abbiamo elencato sopra. Questo tutorial ti guiderà attraverso l'intero sviluppo del codice sia per il server che per il client. Poiché ogni applicazione può utilizzare solo una delle opzioni di ciascuna categoria, vale a dire frontend, trasporto e protocollo, considerando tutte le permutazioni e le combinazioni di queste tre, il numero di applicazioni sarà esorbitante.
Questo tutorial discute in dettaglio lo sviluppo dei seguenti progetti:
CXF con oggetti CXF (POJO) di Apache vecchi e semplici
CXF con JAX-WS
CXF con WSDL
CXF con JAX-RS
CXF con JMS
Per mantenerlo semplice, abbiamo usato Maven con la sua interfaccia a riga di comando. Puoi usare il tuo IDE preferito per creare un progetto maven.
Nel prossimo capitolo, iniziamo con il primo.
In questo capitolo imparerai come sviluppare una semplice applicazione web che invia un messaggio di saluto all'utente. Un progetto di servizio Web utilizza il modello WSDL . Il CXF consente di nascondere questo modello WSDL fornendo un semplice frontend per mappare le API CXF di Apache al WSDL sottostante.
In questo progetto più semplice, l'interfaccia del servizio Web sarà esposta direttamente al client e il client utilizzerà le API CXF Apache native per chiamare il servizio Web.
Per prima cosa creeremo un servizio web. Ogni servizio ha un'interfaccia esposta al client. Possiamo scrivere questa interfaccia come una semplice interfaccia Apache CXF o come un documento WSDL. In questo approccio Apache CXF-First, esporremo il nostro servizio tramite un'interfaccia Apache CXF.
Sviluppo di servizi Web
Il servizio che creeremo sul web avrà un unico metodo web chiamato greetings. Il metodo richiede un filestringtipo di argomento in cui invieremo il nome dell'utente. Il servizio restituirà un messaggio di saluto al chiamante con il nome utente ricevuto incluso nel messaggio.
Interfaccia del servizio Web
Per esporre l'interfaccia del nostro servizio web, creeremo un'interfaccia CXF di Apache come segue:
//HelloWorld.java
package com.tutorialspoint.cxf.pojo;
public interface HelloWorld {
String greetings(String text);
}
L'interfaccia ha un solo metodo chiamato greetings. Il server implementerà questa interfaccia. Nella nostra banale applicazione, questa interfaccia è direttamente esposta al client. In genere, in un'applicazione del servizio Web, si utilizza WSDL per descrivere l'interfaccia del servizio Web. In questa semplice applicazione, forniremo questa interfaccia diretta allo sviluppatore del cliente. Il client chiamerebbe quindi ilgreetingsmessaggio sull'oggetto server. Quindi prima creiamo il servizio web.
Implementazione del servizio Web
Il HelloWorld l'interfaccia è implementata in HelloWorldImpl Classe Apache CXF come mostrato di seguito -
//HelloWorldImpl.java
package com.tutorialspoint.cxf.pojo;
public class HelloWorldImpl implements HelloWorld {
@Override
public String greetings(String text) {
return "Hi " + text;
}
}
Il greetings metodo riceve un parametro di string type, lo aggiunge a un messaggio di saluto e restituisce la stringa risultante al chiamante.
Successivamente, scriviamo l'applicazione server per ospitare il file HelloWorld servizio.
Creazione del server
L'applicazione server è composta da due parti:
La prima parte crea una fabbrica per il nostro servizio web e
La seconda parte scrive a main metodo per istanziarlo.
Il server utilizza ServerFactoryBean classe fornita dalle librerie CXF per esporre il nostro HelloWorldinterfaccia ai client remoti. Quindi, per prima cosa istanziamo il fileServerFactoryBean class e quindi impostare le sue varie proprietà -
ServerFactoryBean factory = new ServerFactoryBean();
Impostiamo la classe di servizio da chiamare chiamando il setServiceClass metodo sul factory oggetto -
factory.setServiceClass(HelloWorld.class);
Abbiamo impostato l'URL per chiamare il nostro servizio chiamando la fabbrica setAddressmetodo. Tieni presente che il servizio verrà pubblicato a questo URL.
factory.setAddress("http://localhost:5000/Hello");
In questo caso, il servizio viene distribuito sul server incorporato e ascolterà la porta 5000. Puoi optare per qualsiasi numero di porta di tua scelta.
Prima di creare la fabbrica, è necessario comunicare alla fabbrica la nostra classe di implementazione del servizio. Questo viene fatto chiamando ilsetServiceBean metodo sul factory oggetto come mostrato qui -
factory.setServiceBean(new HelloWorldImpl());
Il bean di servizio è impostato sull'istanza della nostra classe di implementazione del servizio. Infine, creiamo la fabbrica chiamandolacreate metodo -
factory.create();
Ora, poiché abbiamo sviluppato la fabbrica per eseguire il nostro servizio web, scriveremo in seguito un file main metodo per istanziarlo e mantenerlo in esecuzione per un po 'di tempo.
Ora scrivi un file main metodo per istanziare il HelloServer classe come segue -
public static void main(String[] args) throws Exception {
new HelloServer();
System.out.println("Listening on port 5000 ...");
}
Una volta istanziato, il HelloServerla classe continuerà a funzionare indefinitamente. Per le distribuzioni di produzione, manterrai sicuramente il tuo server in esecuzione per sempre. Nella situazione attuale, chiuderemmo il server dopo un tempo predeterminato come segue:
Thread.sleep(5 * 60 * 1000);
System.out.println("Server exiting ...");
System.exit(0);
L'intero codice per HelloServer la classe è riportata di seguito -
//HelloServer.java
//HelloServer.java
package com.tutorialspoint.cxf.pojo;
import org.apache.cxf.frontend.ServerFactoryBean;
public class HelloServer {
protected HelloServer() throws Exception {
ServerFactoryBean factory = new ServerFactoryBean();
factory.setServiceClass(HelloWorld.class);
factory.setAddress("http://localhost:5000/Hello");
factory.setServiceBean(new HelloWorldImpl());
factory.create();
}
public static void main(String[] args) throws Exception {
new HelloServer();
System.out.println("Listening on port 5000 ...");
Thread.sleep(5 * 60 * 1000);
System.out.println("Server exiting ...");
System.exit(0);
}
}
L'applicazione server che abbiamo creato utilizza ServerFactoryBeanclasse dalle librerie CXF. Ora dobbiamo includere queste librerie nel nostro progetto per compilare con successo il fileHelloServerclasse. Noi useremoMaven per impostare le dipendenze del progetto.
Impostazione del progetto Maven
Per creare un progetto Maven, digita il seguente comando nella finestra della riga di comando. Nota che l'abbiamo testato su una macchina Mac. Per le installazioni Windows e Linux, le istruzioni potrebbero differire in alcuni punti.
mvn archetype:generate
Quando vengono richieste le proprietà, immettere i seguenti valori:
Define value for property 'groupId': : com.tutorialspoint
Define value for property 'artifactId': : cxf-pojo
Define value for property 'version': 1.0-SNAPSHOT: : 1.0
Define value for property 'package': com.tutorialspoint: : com.tutorialspoint.cxf.pojo
Al completamento del comando maven, troverai la struttura di cartelle appropriata creata nella tua cartella corrente insieme al file pom.xml.
La struttura della directory generata è mostrata qui -
Aggiungerai le dipendenze CXF nel file pom.xmle copia anche i file CXF di Apache creati sopra nella cartella appropriata della struttura creata da Maven. Per tua pronta consultazione, abbiamo fornito di seguito il file pom.xml per il progetto che abbiamo creato sulla nostra macchina.
<?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-pojo</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<profiles>
<profile>
<id>server</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.pojo.HelloServer
</mainClass>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</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.pojo.HelloClient
</mainClass>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-features-logging</artifactId>
<version>3.3.0</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-simple</artifactId>
<version>3.3.0</version>
<type>jar</type>
</dependency>
<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-frontend-jaxws</artifactId>
<version>3.3.0</version>
</dependency>
<!-- Jetty is needed if you're using the CXFServlet -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>3.3.0</version>
</dependency>
</dependencies>
<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>
</project>
Il pom.xml sopra può includere dipendenze aggiuntive che sono irrilevanti per questo progetto, ma sono necessarie per il nostro prossimo progetto in questo tutorial. Ad ogni modo, non vi è alcun danno in quanto tale nell'inclusione di dipendenze aggiuntive.
Struttura delle cartelle del progetto
La struttura della cartella del progetto sulla mia macchina dopo aver posizionato i file CXF di Apache del client e del server è mostrata di seguito per una rapida consultazione -
Server in esecuzione
Per creare il progetto, utilizza il seguente comando nella finestra della riga di comando:
mvn clean install
È possibile avviare il server utilizzando il seguente comando:
mvn -Pserver
Questo avvierà il server e vedrai il seguente prompt sulla console:
INFO: Creating Service {http://pojo.cxf.tutorialspoint.com/}HelloWorld from class com.tutorialspoint.cxf.pojo.HelloWorld
INFO: Setting the server's publish address to be http://localhost:5000/Hello
Listening on port 5000 ...
Ora, nella finestra del tuo browser specifica l'URL del nostro servizio pubblicato. Vedrai il seguente output:
Ciò conferma che il nostro servizio è in esecuzione sulla porta specificata su un localhost. Poiché non abbiamo specificato il filegreetings messaggio nella nostra chiamata, al browser viene restituito un messaggio di errore SOAP.
Puoi testare ulteriormente il tuo servizio web utilizzando un client SOAP di tua scelta. Qui abbiamo utilizzato Postman per testare il nostro server.
L'output è come mostrato qui -
Osservalo SOAP Requestè stato codificato a mano. Dopo aver pubblicato la richiesta, il server ha inviato un fileSOAP Response messaggio, visualizzato nella parte inferiore della schermata.
Da ciò, puoi capire che CXF mantiene l'uso dei protocolli SOAP sia per la richiesta che per la risposta, fornendo al contempo una visione unificata di una varietà di tecnologie web che esistono nel mondo di oggi. Ciò semplifica notevolmente lo sviluppo di applicazioni web.
Il nostro prossimo compito è creare un client che utilizzerà il servizio web che hai creato.
Creazione del cliente
Nell'applicazione server HelloWorldè l'interfaccia che espone il nostro servizio web. Il servizio web stesso fornisce solo un semplice messaggio di saluto al client. Di solito, l'interfaccia del servizio Web è esposta al mondo esterno utilizzando WSDL (Web Services Description Language). In questa banale applicazione, esporremo il nostro servizio web al client esponendo direttamente l'interfaccia del servizio e cioè il fileHelloWorld.class.
A tale scopo, CXF fornisce una classe factory chiamata ClientProxyFactoryBean che ci consente di collegarci all'interfaccia desiderata all'istanza di fabbrica creata.
Innanzitutto, creiamo un'istanza di factory bean come segue:
ClientProxyFactoryBean factory = new ClientProxyFactoryBean();
Chiamiamo il file setAddresssull'istanza del factory bean per impostare l'URL mediante il quale il nostro servizio web può essere richiamato. Nel nostro caso, useremo l'URL utilizzato durante la creazione del server nel nostro passaggio precedente -
factory.setAddress("http://localhost:5000/Hello");
Successivamente, chiamiamo il file create metodo sul factory istanza per collegare la nostra interfaccia di servizio HelloWorld.class ad esso.
HelloWorld helloServer = factory.create(HelloWorld.class);
Infine, chiamiamo il file greetings metodo per richiamare il servizio Web remoto.
System.out.println(helloServer.greetings(System.getProperty("user.name")));
Questo stamperebbe un messaggio di saluto sulla tua console.
L'intera fonte per l'applicazione client è mostrata di seguito:
//HelloClient.java
package com.tutorialspoint.cxf.pojo;
import org.apache.cxf.frontend.ClientProxyFactoryBean;
public class HelloClient {
public static void main(String[] args) throws Exception {
ClientProxyFactoryBean factory = new ClientProxyFactoryBean();
factory.setAddress("http://localhost:5000/Hello");
HelloWorld helloServer = factory.create(HelloWorld.class);
System.out.println(helloServer.greetings(System.getProperty("user.name")));
}
}
Client in esecuzione
Assicurati che il server sia ancora in esecuzione sulla tua macchina. In caso, se è scaduto, riavviare il server con il seguente comando:
mvn -Pserver
Vedrai il seguente messaggio sulla console:
Listening on port 5000 ...
Ora, prima che il server scada, che abbiamo impostato su 5 minuti, apri un'altra finestra della riga di comando e avvia il client con il seguente comando:
mvn -Pclient
Vedrai un messaggio simile al seguente sulla riga di comando:
Hi tutorialspoint
Nota che tutorialspointè il nostro nome utente. Riceverai un saluto con il tuo nome.
Nel prossimo capitolo impareremo come utilizzare CXF in un progetto JAX-WS (Apache CXF API for XML Web Services).
In questa applicazione JAX-WS, useremo l'approccio Apache CXF-first come la precedente applicazione POJO. Quindi prima creeremo un'interfaccia per il nostro servizio web.
Dichiarazione dell'interfaccia del servizio
Come nel caso precedente, creeremo un servizio banale che ha un solo metodo di interfaccia chiamato saluti. Il codice per l'interfaccia di servizio è mostrato di seguito -
//HelloWorld.java
package com.tutorialspoint.cxf.jaxws.helloworld;
import javax.jws.WebService;
@WebService
public interface HelloWorld {
String greetings(String text);
}
Annotiamo l'interfaccia con un file @WebServiceetichetta. Successivamente, implementeremo questa interfaccia.
Implementazione dell'interfaccia Web
L'implementazione dell'interfaccia web è mostrata qui -
//HelloWorldImpl.java
package com.tutorialspoint.cxf.jaxws.helloworld;
public class HelloWorldImpl implements HelloWorld {
@Override
public String greetings(String name) {
return ("hi " + name);
}
}
Il metodo dei saluti è annotato con @Overrideetichetta. Il metodo restituisce un messaggio "ciao" al chiamante.
Successivamente, scriveremo il codice per lo sviluppo del server.
Server di sviluppo
A differenza dell'applicazione POJO, ora disaccoppieremo l'interfaccia utilizzando la classe Endpoint fornita da CXF per pubblicare il nostro servizio. Questo viene fatto nelle seguenti due righe di codice:
HelloWorld implementor = new HelloWorldImpl();
Endpoint.publish(
"http://localhost:9090/HelloServerPort",
implementor,
new LoggingFeature()
);
Il primo parametro del metodo di pubblicazione specifica l'URL al quale il nostro servizio sarà reso disponibile ai client. Il secondo parametro specifica la classe di implementazione per il nostro servizio. L'intero codice per il server è mostrato di seguito -
//Server.java
package com.tutorialspoint.cxf.jaxws.helloworld;
import javax.xml.ws.Endpoint;
import org.apache.cxf.ext.logging.LoggingFeature;
public class Server {
public static void main(String[] args) throws Exception {
HelloWorld implementor = new HelloWorldImpl();
Endpoint.publish("http://localhost:9090/HelloServerPort",
implementor,
new LoggingFeature());
System.out.println("Server ready...");
Thread.sleep(5 * 60 * 1000);
System.out.println("Server exiting ...");
System.exit(0);
}
}
Per distribuire il nostro server, dovrai apportare alcune modifiche al tuo progetto come elencato di seguito.
Distribuzione del server
Infine, per distribuire l'applicazione server, dovrai apportare un'altra modifica in pom.xml per configurare la tua applicazione come applicazione web. Il codice che devi aggiungere al tuo filepom.xml è dato di seguito -
<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.jaxws.helloworld.Server
</mainClass>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
Prima di distribuire l'applicazione, è necessario aggiungere altri due file al progetto. Questi sono mostrati nello screenshot qui sotto:
Questi file sono file standard CXF che definiscono la mappatura per CXFServlet. Il codice all'interno diweb.xml file viene mostrato qui per una rapida consultazione -
//Web.xml
<?xml version = "1.0" encoding = "UTF-8"??>
<web-app xmlns = "http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.5"
xsi:schemaLocation = "http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>cxf</display-name>
<servlet>
<description>Apache CXF Endpoint</description>
<display-name>cxf</display-name>
<servlet-name>cxf</servlet-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
<load-on-startup>
1
</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>
cxf
</servlet-name>
<url-pattern>
/services/*
</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>60</session-timeout>
</session-config>
</web-app>
Nel cxf-servlet.xml,dichiari le proprietà per l'endpoint del tuo servizio. Questo è mostrato nello snippet di codice di seguito:
<beans ...>
<jaxws:endpoint xmlns:helloworld = "http://tutorialspoint.com/"
id = "helloHTTP"
address = "http://localhost:9090/HelloServerPort"
serviceName = "helloworld:HelloServiceService"
endpointName = "helloworld:HelloServicePort">
</jaxws:endpoint>
</beans>
Qui definiamo l'id per il nostro endpoint del servizio, l'indirizzo su cui il servizio sarà disponibile, il nome del servizio e il nome dell'endpoint. Ora, hai imparato come il tuo servizio viene instradato ed elaborato da un servlet CXF.
The Final pom.xml
Il pom.xmlinclude alcune dipendenze in più. Piuttosto che descrivere tutte le dipendenze, abbiamo incluso la versione finale di pom.xml di seguito -
<?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-jaxws</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.jaxws.helloworld.Server
</mainClass>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</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.jaxws.helloworld.Client
</mainClass>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.3.0</version>
</dependency>
<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-features-logging</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>
</dependencies>
</project>
Si noti che include anche un profilo per la creazione del client che apprenderemo nelle sezioni successive di questo tutorial.
Esecuzione del servizio HelloWorld
Ora sei pronto per eseguire l'app Web. Nella finestra dei comandi, esegui lo script di compilazione utilizzando il seguente comando.
mvn clean install
mvn -Pserver
Vedrai il seguente messaggio sulla console:
INFO: Setting the server's publish address to be http://localhost:9090/HelloServerPort
Server ready…
Come in precedenza, puoi testare il server aprendo l'URL del server nel tuo browser.
Poiché non abbiamo specificato alcuna operazione, solo un messaggio di errore viene restituito al browser dalla nostra applicazione.
Ora prova ad aggiungere il file ?wsdl al tuo URL e vedrai il seguente output:
Quindi la nostra applicazione server funziona come previsto. È possibile utilizzare il client SOAP comePostman descritto in precedenza per testare ulteriormente il servizio.
Nella prossima sezione impareremo come scrivere un client che utilizza il nostro servizio.
Cliente in sviluppo
Scrivere il client in un'applicazione CXF è banale come scrivere un server. Ecco il codice completo per il client -
//Client.java
package com.tutorialspoint.cxf.jaxws.helloworld;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import javax.xml.ws.soap.SOAPBinding;
public final class Client {
private static final QName SERVICE_NAME
= new QName("http://helloworld.jaxws.cxf.tutorialspoint.com/",
"HelloWorld");
private static final QName PORT_NAME
= new QName("http://helloworld.jaxws.cxf.tutorialspoint.com/",
"HelloWorldPort");
private Client() {
}
public static void main(String[] args) throws Exception {
Service service = Service.create(SERVICE_NAME);
System.out.println("service created");
String endpointAddress = "http://localhost:9090/HelloServerPort";
service.addPort(PORT_NAME, SOAPBinding.SOAP11HTTP_BINDING,
endpointAddress);
HelloWorld hw = service.getPort(HelloWorld.class);
System.out.println(hw.greetings("World"));
}
}
Qui utilizziamo il CXF fornito Serviceclasse da associare al servizio noto. Chiamiamo il filecreate metodo sul Serviceclass per ottenere un'istanza del servizio. Impostiamo la porta nota chiamando iladdPort metodo sul service esempio.
Ora siamo pronti per utilizzare il servizio, cosa che facciamo ottenendo prima l'interfaccia del servizio chiamando il getPort metodo sul serviceesempio. Infine, chiamiamo nostrogreetings metodo per stampare il messaggio di saluto sulla console.
Dopo aver appreso le basi di CXF utilizzando l'approccio Apache CXF-First, imparerai ora come utilizzare CXF con l'approccio WSDL-First nel prossimo capitolo.
L'applicazione CXF-POJO che avete sviluppato risulta in un accoppiamento molto stretto tra il client e il server. Anche fornire un accesso diretto all'interfaccia del servizio può rappresentare gravi minacce alla sicurezza. Pertanto, di solito si desidera il disaccoppiamento tra il client e il server, che si ottiene utilizzando WSDL (Web Services Description Language).
Scriviamo l'interfaccia del servizio web in un documento WSDL che è basato su XML. Useremo uno strumento per mappare questo WSDL alle interfacce Apache CXF che vengono poi implementate e utilizzate dalle nostre applicazioni client e server. Per fornire il disaccoppiamento, è preferibile iniziare con un WSDL. Per questo, devi prima imparare una nuova lingua: WSDL. La scrittura di WSDL richiede un approccio attento e sarebbe meglio se tu potessi ottenere una certa comprensione su questo prima di iniziare a lavorarci.
In questa lezione, inizieremo definendo un'interfaccia del servizio Web in un documento WSDL. Impareremo come utilizzare CXF per creare applicazioni server e client a partire da WSDL. Manterremo l'applicazione semplice per mantenere l'attenzione sull'uso di CXF. Dopo aver creato l'applicazione server, la pubblicheremo nell'URL desiderato utilizzando una classe CXF incorporata.
Innanzitutto, descriviamo il WSDL che utilizzeremo.
WSDL per HelloWorld
Il servizio web che implementeremo avrà un unico metodo web chiamato greetings che accetta a stringparametro contenente il nome utente e restituisce un messaggio di stringa al chiamante dopo aver aggiunto un messaggio di saluto al nome utente. Il wsdl completo è mostrato di seguito:
//Hello.wsdl
<?xml version = "1.0" encoding = "UTF-8"?>
<wsdl:definitions xmlns:soap = "http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns = "http://helloworld.tutorialspoint.com/"
xmlns:wsdl = "http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd = "http://www.w3.org/2001/XMLSchema"
name = "HelloWorld"
targetNamespace = "http://helloworld.tutorialspoint.com/">
<wsdl:types>
<xsd:schema attributeFormDefault = "unqualified"
elementFormDefault = "qualified"
targetNamespace = "http://helloworld.tutorialspoint.com/">
<xsd:element name = "greetings" type = "tns:greetings"/>
<xsd:complexType name = "greetings">
<xsd:sequence>
<xsd:element minOccurs = "0" name = "arg0" type = "xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name = "greetingsResponse"
type = "tns:greetingsResponse"/>
<xsd:complexType name = "greetingsResponse">
<xsd:sequence>
<xsd:element minOccurs = "0" name = "return" type = "xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
</wsdl:types>
<wsdl:message name = "greetings">
<wsdl:part element = "tns:greetings" name = "parameters"> </wsdl:part>
</wsdl:message>
<wsdl:message name = "greetingsResponse">
<wsdl:part element = "tns:greetingsResponse" name = "parameters"> </wsdl:part>
</wsdl:message>
<wsdl:portType name = "HelloWorldPortType">
<wsdl:operation name = "greetings">
<wsdl:input message = "tns:greetings" name = "greetings"> </wsdl:input>
<wsdl:output message = "tns:greetingsResponse" name = "greetingsResponse">
</wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name = "HelloWorldSoapBinding" type = "tns:HelloWorldPortType">
<soap:binding style = "document"
transport = "http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name = "greetings">
<soap:operation soapAction = "" style = "document"/>
<wsdl:input name = "greetings"></wsdl:input>
<wsdl:output name = "greetingsResponse">
<soap:body use = "literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name = "HelloWorldService">
<wsdl:port binding = "tns:HelloWorldSoapBinding" name = "HelloWorldPort">
<soap:address location = "http://localhost:9090/HelloServerPort"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Notare che scrivere un wsdl sintatticamente corretto è sempre stata una sfida per gli sviluppatori; ci sono molti strumenti e sono disponibili editor online per creare un wsdl. Questi editor richiedono i nomi dei messaggi che si desidera implementare insieme ai parametri che si desidera passare in un messaggio e il tipo di messaggio di ritorno che si desidera ricevere dall'applicazione client. Se conosci la sintassi wsdl, puoi codificare manualmente l'intero documento o utilizzare uno degli editor per crearne uno tuo.
Nel wsdl sopra, abbiamo definito un singolo messaggio chiamato greetings. Il messaggio viene consegnato al servizio chiamatoHelloWorldService che sta funzionando a http://localhost:9090/HelloServerPort.
Con questo, procederemo ora allo sviluppo del server. Prima di sviluppare il server, dobbiamo generare l'interfaccia Apache CXF per il nostro servizio web. Questo deve essere fatto dal dato wsdl. Per fare ciò, usi uno strumento chiamatowsdl2java.
Il plugin wsdl2java
Poiché utilizzeremo Maven per creare il progetto, sarà necessario aggiungere il seguente plug-in al file pom.xml file.
<plugins>
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<wsdlOptions>
<wsdlOption>
<wsdl>src/main/resources/hello.wsdl</wsdl>
<faultSerialVersionUID> 1 </faultSerialVersionUID>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
Nota che specifichiamo la posizione del file wsdl file come src/main/resources/Hello.wsdl. Dovrai assicurarti di creare una struttura di directory appropriata per il tuo progetto e aggiungere quella mostrata in precedenzahello.wsdl file nella cartella specificata.
Il wsdl2javaplugin compilerà questo wsdl e creerà classi CXF di Apache in una cartella predefinita. La struttura completa del progetto è mostrata qui come riferimento immediato.
Ora sei pronto per creare un server usando il wsdl2javaclassi generate. Le classi create da wsdl2java sono mostrate nella figura seguente:
Interfaccia di servizio generata
Nell'elenco delle classi generate, devi aver notato che una di esse è un'interfaccia CXF di Apache: questa è HelloWorldPortType.java. Esamina questo file nel tuo editor di codice. Il contenuto del file viene mostrato qui come riferimento pronto -
//HelloWorldPortType.java
package com.tutorialspoint.helloworld;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;
/**
* This class was generated by Apache CXF 3.3.0
* 2019-02-11T12:05:55.220+05:30
* Generated source version: 3.3.0
*
*/
@WebService(targetNamespace = "http://helloworld.tutorialspoint.com/",
name = "HelloWorldPortType")
@XmlSeeAlso({ObjectFactory.class})
public interface HelloWorldPortType {
@WebMethod
@RequestWrapper(localName = "greetings", targetNamespace =
"http://helloworld.tutorialspoint.com/", className =
"com.tutorialspoint.helloworld.Greetings")
@ResponseWrapper(localName = "greetingsResponse", targetNamespace =
"http://helloworld.tutorialspoint.com/", className =
"com.tutorialspoint.helloworld.GreetingsResponse")
@WebResult(name = "return", targetNamespace =
"http://helloworld.tutorialspoint.com/")
public java.lang.String greetings(
@WebParam(name = "arg0", targetNamespace =
"http://helloworld.tutorialspoint.com/")
java.lang.String arg0
);
}
Notare che l'interfaccia contiene un metodo chiamato greetings. Questo era un tipo di messaggio nel nostro wsdl. Ilwsdl2javalo strumento ha aggiunto questo metodo all'interfaccia generata. Ora puoi capire che qualunque messaggio tu scrivi nel tuo wsdl, un metodo corrispondente verrebbe generato nell'interfaccia.
Ora, il tuo compito sarebbe implementare tutti questi metodi corrispondenti ai vari messaggi che hai definito nel tuo wsdl. Si noti che nel precedente esempio di Apache CXF-First, abbiamo iniziato con un'interfaccia Apache CXF per il nostro servizio web. In questo caso, l'interfaccia di Apache CXF viene creata da wsdl.
Implementazione dell'interfaccia del servizio
L'implementazione dell'interfaccia del servizio è banale. L'implementazione completa è mostrata nell'elenco seguente:
//HelloWorldImpl.java
package com.tutorialspoint.helloworld;
public class HelloWorldImpl implements HelloWorldPortType {
@Override
public String greetings(String name) {
return ("hi " + name);
}
}
Il codice implementa l'unico metodo di interfaccia chiamato greetings. Il metodo accetta un parametro distring type, antepone un messaggio "hi" e restituisce la stringa risultante al chiamante.
Successivamente, scriveremo l'applicazione server.
Server di sviluppo
Lo sviluppo di applicazioni server è ancora una volta banale. Qui utilizzeremo il CXF fornitoEndpointclass per pubblicare il nostro servizio. Questo viene fatto nelle seguenti due righe di codice:
HelloWorldPortType implementor = new HelloWorldImpl();
Endpoint.publish("http://localhost:9090/HelloServerPort",
implementor,
new LoggingFeature());
Per prima cosa, creiamo un oggetto della nostra classe di implementazione del servizio - HelloWorldImpl. Quindi, passiamo questo riferimento come secondo parametro al filepublishmetodo. Il primo parametro è l'indirizzo in cui è pubblicato il servizio: i client utilizzerebbero questo URL per accedere al servizio. L'intera fonte per l'applicazione server è fornita qui:
//Server.java
package com.tutorialspoint.helloworld;
import javax.xml.ws.Endpoint;
import org.apache.cxf.ext.logging.LoggingFeature;
public class Server {
public static void main(String[] args) throws Exception {
HelloWorldPortType implementor = new HelloWorldImpl();
Endpoint.publish("http://localhost:9090/HelloServerPort",
implementor,
new LoggingFeature());
System.out.println("Server ready...");
Thread.sleep(5 * 60 * 1000);
System.out.println("Server exiting");
System.exit(0);
}
}
Per costruire questa classe server dovrai aggiungere un profilo di build nel tuo file pom.xml. Questo è mostrato di seguito -
<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.helloworld.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>
Notare che il nome completo di Serverclass è specificato nella configurazione. Inoltre, il tag di dipendenza specifica che utilizzeremo il server web jetty incorporato per distribuire la nostra applicazione server.
Distribuzione del server
Infine, per distribuire l'applicazione server, dovrai apportare un'altra modifica in pom.xml per configurare la tua applicazione come applicazione web. Il codice che devi aggiungere al tuo filepom.xml è dato di seguito -
<defaultGoal>install</defaultGoal>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<webXml>src/main/webapp/WEB-INF/web.xml</webXml>
<webResources>
<resource>
<directory>src/main/resources</directory>
<targetPath>WEB-INF</targetPath>
<includes>
<include>*.wsdl</include>
</includes>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>
</pluginManagement>
Prima di distribuire l'applicazione, è necessario aggiungere altri due file al progetto. Questi sono mostrati nello screenshot qui sotto:
Questi file sono file standard CXF che definiscono la mappatura per CXFServlet. Il codice all'interno diweb.xml file viene mostrato qui per una rapida consultazione -
//cxf-servlet.xml
<web-app xmlns = "http://java.sun.com/xml/ns/javaee"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" version="2.5"
xsi:schemaLocation = "http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>cxf</display-name>
<servlet>
<description>Apache CXF Endpoint</description>
<display-name>cxf</display-name>
<servlet-name>cxf</servlet-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>cxf</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>60</session-timeout>
</session-config>
</web-app>
Nel cxf-servlet.xmldichiari le proprietà per l'endpoint del tuo servizio. Questo è mostrato nello snippet di codice di seguito:
<beans ...>
<jaxws:endpoint xmlns:helloworld = "http://tutorialspoint.com/"
id="helloHTTP"
address = "http://localhost:9090/HelloServerPort"
serviceName = "helloworld:HelloServiceService"
endpointName = "helloworld:HelloServicePort">
</jaxws:endpoint>
</beans>
Qui definiamo l'id per il nostro endpoint del servizio, l'indirizzo su cui il servizio sarà disponibile, il nome del servizio e il nome dell'endpoint. Ora capisci come il tuo servizio viene instradato ed elaborato da un servlet CXF.
The Final pom.xml
Il pom.xmlinclude alcune dipendenze in più. Piuttosto che descrivere tutte le dipendenze, abbiamo incluso la versione finale di pom.xml di seguito -
<?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-wsdl</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>
<build>
<defaultGoal>install</defaultGoal>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<webXml>src/main/webapp/WEB-INF/web.xml</webXml>
<webResources>
<resource>
<directory>src/main/resources</directory>
<targetPath>WEB-INF</targetPath>
<includes>
<include>*.wsdl</include>
</includes>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<wsdlOptions>
<wsdlOption>
<wsdl>src/main/resources/Hello.wsdl</wsdl>
<faultSerialVersionUID>1</faultSerialVersionUID>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<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.helloworld.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.helloworld.Client
</mainClass>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.3.0</version>
</dependency>
<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-management</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-features-metrics</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.cxf.xjc-utils</groupId>
<artifactId>cxf-xjc-runtime</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-features-logging</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.6.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.8.0-beta2</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>3.3.0</version>
</dependency>
</dependencies>
</project>
Si noti che include anche un profilo per la creazione del cliente che apprenderemo presto nelle sezioni successive.
Esecuzione del servizio HelloWorld
Ora sei pronto per eseguire l'app Web. Nella finestra dei comandi, esegui lo script di compilazione utilizzando il seguente comando.
mvn clean install
Questo genererà le classi Apache CXF appropriate dal tuo wsdl, compilerà le tue classi Apache CXF, distribuirà il server sul jetty server incorporato ed eseguirà la tua applicazione.
Vedrai il seguente messaggio sulla console:
INFO: Setting the server's publish address to be
http://localhost:9090/HelloServerPort
Server ready...
Come prima, puoi testare il server aprendo l'URL del server nel tuo browser.
Poiché non abbiamo specificato alcuna operazione, solo un messaggio di errore viene restituito al browser dalla nostra applicazione. Ora prova ad aggiungere il file?wsdl al tuo URL e vedrai il seguente output:
Quindi la nostra applicazione server funziona come previsto. È possibile utilizzare il client SOAP comePostman descritto in precedenza per testare ulteriormente il servizio.
La parte successiva di questo tutorial è scrivere un client che utilizzi il nostro servizio.
Cliente in sviluppo
La scrittura del client in un'applicazione CXF è importante quanto la scrittura di un server. Ecco il codice completo per il client che consiste essenzialmente di sole tre righe, il resto delle righe stampa solo le informazioni sul servizio all'utente.
//Client.java
package com.tutorialspoint.helloworld;
public class Client {
public static void main(String[] args) throws Exception {
//Create the service client with its default wsdlurl
HelloWorldService helloServiceService = new HelloWorldService();
System.out.println("service: " +
helloServiceService.getServiceName());
System.out.println("wsdl location: " +
helloServiceService.getWSDLDocumentLocation());
HelloWorldPortType helloService =
helloServiceService.getHelloWorldPort();
System.out.println(helloService.greetings
(System.getProperty("user.name")));
}
}
Qui creiamo semplicemente un'istanza del nostro servizio HelloWorldService, ottieni il suo porto chiamando getHelloWorldPort metodo, quindi passa il nostro greetingsmessaggio ad esso. Esegui il client e vedrai il seguente output:
service: {http://helloworld.tutorialspoint.com/}HelloWorldService
wsdl location: file:/Users/drsarang/Desktop/tutorialpoint/cxf-
wsdl/src/main/resources/Hello.wsdl
hi drsarang
Finora hai imparato a usare CXF con le architetture Apache CXF-First e WSDL-First. Nell'approccio Apache CXF-First, hai utilizzato un POJO conServerFactoryBeanclass dalle librerie CXF per creare un server. Per creare un cliente che hai usatoClientProxyFactoryBeanclasse dalla libreria CXF. Nell'approccio WSDL-First, hai utilizzatoEndpointclass per pubblicare il servizio all'URL desiderato e un implementatore specificato. È ora possibile estendere queste tecniche per integrare diversi protocolli e trasporti.
Prima di procedere in questo capitolo, presumiamo che tu sappia come scrivere un servizio web RESTful in Java. Ti mostrerò come utilizzare CXF in cima a questo JAX-RS (API Java per servizi Web RESTful). Creeremo un servizio web che mantiene un elenco degli ultimi film. Quando l'utente richiede un film, specifica l'ID del film nella sua richiesta, il server individuerà il film e lo restituirà al client. Nel nostro caso banale, restituiremo semplicemente il nome del film al client e non il file binario MP4 effettivo. Quindi iniziamo a creare un'applicazione JAX-RS.
Dichiarazione dell'elemento filmato
Dichiareremo un elemento radice XML chiamato Movie per memorizzare l'id e il nome di un determinato film. L'elemento è dichiarato in un file chiamato Movie.java. Il contenuto del file è mostrato qui -
//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;
}
}
Nota l'uso di XmlRootElement tag per dichiarare l'elemento XML per il Movieetichetta. Successivamente, creeremo un servizio che contiene l'elenco dei film nel suo database.
Creazione del database del servizio di film
Per memorizzare l'elenco dei film utilizziamo Java fornito Mapche memorizza le coppie chiave-valore. Se l'elenco è grande, utilizzerai un archivio di database esterno che sarà anche più facile da gestire. Nel nostro caso banale, memorizzeremo solo cinque film nel nostro database. Il codice per la classe MovieService è fornito di seguito:
//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);
}
}
Nota che usiamo le seguenti due annotazioni per specificare il percorso dell'URL per il nostro servizio di film e il suo tipo di ritorno -
@Path("/movieservice/")
@Produces("text/xml")
Usiamo le annotazioni @GET e @Path per specificare l'URL per la richiesta GET come segue:
@GET
@Path("/movie/{id}/")
Il database del film stesso viene inizializzato nel metodo init, dove aggiungiamo cinque elementi del film al database.
Il nostro prossimo compito è scrivere un'applicazione server.
Server di sviluppo
Per creare un server, utilizziamo CXF fornito JAXRSServerFactoryBean classe.
JAXRSServerFactoryBean factory = new JAXRSServerFactoryBean();
Impostiamo le sue classi di risorse chiamando il setResourceClasses metodo.
factory.setResourceClasses(Movie.class);
factory.setResourceClasses(MovieService.class);
Impostiamo il fornitore di servizi chiamando il setResourceProvider metodo.
factory.setResourceProvider(MovieService.class,
new SingletonResourceProvider(new MovieService()));
Impostiamo il desiderato publish indirizzo chiamando il aetAddress metodo -
factory.setAddress("http://localhost:9000/");
Infine, pubblichiamo il server chiamando il metodo create nel file factory esempio.
factory.create();
Di seguito è fornito l'intero codice per l'applicazione server:
//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);
}
}
The Final pom.xml
Qui abbiamo incluso la versione finale di pom.xml di seguito -
<?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>
Cliente in sviluppo
Scrivere il client RS è banale. Creiamo semplicemente un oggetto URL e apriamo il suo flusso. Usiamo la classe IOUtils fornita da CXF per copiare il contenuto del flusso di input in un flusso locale.
URL url = new URL("http://localhost:9000/movieservice/movie/1002");
try (InputStream instream = url.openStream();
CachedOutputStream outstream = new CachedOutputStream()) {
IOUtils.copy(instream, outstream);
}
Di seguito viene fornito l'intero codice dell'applicazione client:
//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 dell'applicazione JAX-RS
Eseguire il server utilizzando il seguente comando nella finestra della riga di comando:
mvn -Pserver
Ora vedrai il seguente messaggio sulla console:
INFO: Setting the server's publish address to be http://localhost:9000
Ora apri il browser e digita il seguente URL:
http://localhost:9000/movieservice/movie/1002
Vedrai quanto segue nella finestra del browser.
È possibile richiamare il servizio utilizzando un'applicazione client Java che abbiamo sviluppato eseguendo il seguente comando in una finestra della riga di comando separata.
mvn -Pclient
Vedrai il seguente output:
<?xml version="1.0" encoding = "UTF-8" standalone="yes"?>
<Movie><id>1002</id><name>Mission Imposssible</name></Movie>
Gli esempi CXF forniscono diversi esempi su come utilizzare CXF con JAX-RS. I lettori interessati sono incoraggiati a studiare questi campioni.
Come accennato in precedenza, è possibile utilizzare CXF con il trasporto JMS. In questo caso, il client invierà un messaggio JMS a un server di messaggistica noto. La nostra applicazione server ascolta continuamente il server di messaggistica per i messaggi in arrivo. Quando il messaggio arriva, elabora il messaggio, esegue la richiesta del client e invia la risposta come un altro messaggio al client.
Come in precedenza, creeremo prima un'applicazione server di esempio che fornisce un metodo Web singolare chiamato sayHi.
Creazione dell'interfaccia di servizio
L'interfaccia di servizio per il nostro HelloWorld il servizio è mostrato qui -
//HelloWorld.java
package com.tutorialspoint.service;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
@WebService
public interface HelloWorld {
@WebMethod
String sayHi(@WebParam(name = "name") String name);
}
Servizio di implementazione
L'implementazione dell'interfaccia del servizio è definita come segue:
//HelloWorldImpl.java
package com.tutorialspoint.service.impl;
import javax.jws.WebService;
import com.tutorialspoint.service.HelloWorld;
@WebService
public class HelloWorldImpl implements HelloWorld {
@Override
public String sayHi(String name) {
return "Hello " + name;
}
}
L'implementazione restituisce semplicemente un messaggio Hello all'utente. Come vedi, l'interfaccia e la sua implementazione sono simili a tutti i progetti precedenti in questo tutorial che hai studiato finora.
Ora, arriva il punto più importante che è creare un'applicazione server che configuri una coda di messaggi e continui ad ascoltare i messaggi in arrivo.
Creazione del server
Nell'applicazione server, creiamo prima un file JMS punto finale come segue -
private static final String JMS_ENDPOINT_URI =
"jms:queue:test.cxf.jmstransport.queue?timeToLive=1000"
+ "&jndiConnectionFactoryName=ConnectionFactory"
+ "&jndiInitialContextFactory"
+ "= org.apache.activemq.jndi.ActiveMQInitialContextFactory"
+ "&jndiURL = tcp://localhost:61616";
Notare che abbiamo impostato una coda su una porta specificata che vive per un periodo di tempo specificato. Ora creiamo un servizio di messaggistica creando un'istanzaorg.apache.activemq.broker.BrokerServiceclasse. Questa è una classe server perActiveMQ server di messaggistica.
BrokerService broker = new BrokerService();
Puoi utilizzare qualsiasi altro server di messaggistica di tua scelta diverso da ActiveMQ. Ora colleghiamo questo server a un URI desiderato.
broker.addConnector("tcp://localhost:61616");
Abbiamo impostato la directory per l'archiviazione dei dati dei messaggi in arrivo -
broker.setDataDirectory("target/activemq-data");
Infine, avviamo il server utilizzando il metodo di avvio -
broker.start();
Successivamente, creiamo un'istanza del nostro bean di servizio HelloWorld utilizzando la classe bean di fabbrica del server utilizzata nella nostra precedente applicazione POJO -
Object implementor = new HelloWorldImpl();
JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();
factory.setServiceClass(HelloWorld.class);
Successivamente, configuriamo l'endpoint JMS in fabbrica in modo che la fabbrica continui ad ascoltare i messaggi in arrivo -
factory.setTransportId
(JMSSpecConstants.SOAP_JMS_SPECIFICATION_TRANSPORTID);
factory.setAddress(JMS_ENDPOINT_URI);
Infine, configuriamo la classe implementer in fabbrica e iniziamo a eseguirla -
factory.setServiceBean(implementor);
factory.create();
A questo punto il tuo server è attivo e funzionante. Notare che poiché abbiamo utilizzato la classe factory bean come nell'applicazione POJO, la necessità di CXFServlet e del file web.xml non è richiesta.
Il codice completo dell'applicazione server è mostrato qui -
//ServerJMS.java
package com.tutorialspoint.server;
import java.util.Collections;
import org.apache.cxf.ext.logging.LoggingFeature;
import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
import org.apache.cxf.transport.jms.spec.JMSSpecConstants;
import com.tutorialspoint.service.HelloWorld;
import com.tutorialspoint.service.impl.HelloWorldImpl;
import org.apache.activemq.broker.BrokerService;
public final class ServerJMS {
private static final String JMS_ENDPOINT_URI =
"jms:queue:test.cxf.jmstransport.queue?timeToLive=1000"
+ "&jndiConnectionFactoryName=ConnectionFactory"
+ "&jndiInitialContextFactory"
+ "= org.apache.activemq.jndi.ActiveMQInitialContextFactory"
+ "&jndiURL = tcp://localhost:61616";
public static void main(String[] args) throws Exception {
BrokerService broker = new BrokerService();
broker.addConnector("tcp://localhost:61616");
broker.setDataDirectory("target/activemq-data");
broker.start();
Object implementor = new HelloWorldImpl();
JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();
factory.setServiceClass(HelloWorld.class);
factory.setTransportId
(JMSSpecConstants.SOAP_JMS_SPECIFICATION_TRANSPORTID);
factory.setAddress(JMS_ENDPOINT_URI);
factory.setServiceBean(implementor);
factory.setFeatures(Collections.singletonList(new LoggingFeature()));
factory.create();
System.out.println("Server ready...");
Thread.sleep(5 * 60 * 1000);
System.out.println("Server exiting");
System.exit(0);
}
}
Aggiunta di dipendenze
L'applicazione server che abbiamo creato utilizza il server di messaggistica ActiveMQ. Pertanto, dovrai aggiungere poche altre dipendenze al tuo progetto. Il file pom.xml completo viene mostrato qui per consentirti di comprendere le dipendenze aggiuntive necessarie.
<?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-jms</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.server.ServerJMS
</mainClass>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</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.client.ClientJMS
</mainClass>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-broker</artifactId>
<version>5.15.8</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-kahadb-store</artifactId>
<version>5.15.8</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-jms</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-features-logging</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>
</dependencies>
</project>
Server in esecuzione
Per avviare l'esecuzione del server, come nei casi precedenti, digita il seguente comando nella finestra di comando:
mvn -Pserver
Questo avvierà il server dei messaggi ActiveMQ, configurerà la coda di messaggistica e creerà un bean di fabbrica che continuerà ad ascoltare questa coda.
Il nostro prossimo compito è creare un'applicazione client.
Creazione del cliente
Nell'applicazione client, per prima cosa configuriamo l'endpoint JMS come quello utilizzato nell'applicazione server -
private static final String JMS_ENDPOINT_URI =
"jms:queue:test.cxf.jmstransport.queue?timeToLive=1000"
+ "&jndiConnectionFactoryName=ConnectionFactory"
+ "&jndiInitialContextFactory"
+ " = org.apache.activemq.jndi.ActiveMQInitialContextFactory"
+ "&jndiURL = tcp://localhost:61616";
Creiamo una fabbrica come nell'applicazione POJO.
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
Impostiamo l'URI dell'endpoint e la classe implementatore come segue:
factory.setTransportId (JMSSpecConstants.SOAP_JMS_SPECIFICATION_TRANSPORTID);
factory.setAddress (JMS_ENDPOINT_URI);
HelloWorld client = factory.create(HelloWorld.class);
Infine, chiamiamo il metodo di servizio e stampiamo il suo output risultante -
String reply = client.sayHi("TutorialsPoint");
System.out.println(reply);
Il codice cliente completo è fornito di seguito:
// ClientJMS.java
package com.tutorialspoint.client;
import com.tutorialspoint.service.HelloWorld;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.apache.cxf.transport.jms.spec.JMSSpecConstants;
public final class ClientJMS {
private static final String JMS_ENDPOINT_URI =
"jms:queue:test.cxf.jmstransport.queue?timeToLive=1000"
+ "&jndiConnectionFactoryName=ConnectionFactory"
+ "&jndiInitialContextFactory"
+ " = org.apache.activemq.jndi.ActiveMQInitialContextFactory"
+ "&jndiURL = tcp://localhost:61616";
public static void main(String[] args) throws Exception {
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setTransportId(JMSSpecConstants.SOAP_JMS_SPECIFICATION_TRANSPORTID);
factory.setAddress(JMS_ENDPOINT_URI);
HelloWorld client = factory.create(HelloWorld.class);
String reply = client.sayHi("TutorialsPoint");
System.out.println(reply);
System.exit(0);
}
}
Apache CXF - Conclusione
CXF fornisce un approccio unificato per combinare e abbinare diversi protocolli Web e trasporti esistenti nel mondo di oggi per la creazione di applicazioni Web. Hai imparato come iniziare con un'interfaccia Java tradizionale per creare un'applicazione web che utilizza CXF. Successivamente, hai imparato a creare un'applicazione web e il suo client a partire da WSDL.
Il WSDL fornisce una rappresentazione XML dell'interfaccia del servizio. Hai utilizzato lo strumento wsdl2java per creare interfacce Java da WSDL e infine hai scritto sia il server che il client utilizzando le interfacce create. Il tutorial ha anche introdotto brevemente l'utilizzo di CXF nell'applicazione del servizio Web RESTful. Infine, abbiamo anche discusso di come CXF può essere utilizzato con JMS. È ora possibile fare riferimento ai campioni CXF per ulteriori studi.
Note - L'intero codice sorgente del progetto può essere scaricato da qui.