En guide til Apache CXF med foråret

1. Oversigt

Denne vejledning fokuserer på konfiguration og ved hjælp af Apache CXF-rammen sammen med Spring - enten med Java- eller XML-konfiguration.

Det er det andet i en serie om Apache CXF; den første fokuserede på det grundlæggende i CXF som en implementering af JAX-WS standard API'er.

2. Maven-afhængigheder

I lighed med den foregående vejledning skal følgende to afhængigheder medtages:

 org.apache.cxf cxf-rt-frontend-jaxws 3.1.6 org.apache.cxf cxf-rt-transporterer-http 3.1.6 

For de nyeste versioner af Apache CXF artefakter, se venligst apache-cxf.

Derudover er følgende afhængigheder nødvendige for at støtte Spring:

 org.springframework spring-context 4.3.1.RELEASE org.springframework spring-webmvc 4.3.1.RELEASE 

De nyeste versioner af forårets artefakter kan findes her.

Endelig, fordi vi programmatisk konfigurerer applikationen ved hjælp af Java Servlet 3.0+ API i stedet for en traditionel web.xml implementeringsbeskrivelse, vi har brug for artefakten nedenfor:

 javax.servlet javax.servlet-api 3.1.0 

Det er her, vi kan finde den nyeste version af Servlet API.

3. Komponenter på serversiden

Lad os nu se på de komponenter, der skal være til stede på serversiden for at udgive webservicens slutpunkt.

3.1. WebApplicationInitilizer Interface

Det WebApplicationInitializer interface er implementeret for at programmatisk konfigurere ServletContext interface til applikationen. Når det er til stede på klassestien, er det onStartup metoden påkaldes automatisk af servletbeholderen og derefter ServletContext initieres og initialiseres.

Her er hvordan en klasse er defineret til at implementere WebApplicationInitializer grænseflade:

offentlig klasse AppInitializer implementerer WebApplicationInitializer {@ Override public void onStartup (ServletContext container) {// Metodeimplementering}}

Det onStartup () metoden er implementeret ved hjælp af kodestykker vist nedenfor.

Først oprettes og konfigureres en Spring-applikationskontekst til at registrere en klasse, der indeholder konfigurationsmetadata:

AnnotationConfigWebApplicationContext context = ny AnnotationConfigWebApplicationContext (); context.register (ServiceConfiguration.class);

Det ServiceConfiguration klasse er kommenteret med @Konfiguration kommentar for at give bønnedefinitioner. Denne klasse diskuteres i næste afsnit.

Følgende uddrag viser, hvordan Spring-applikationskonteksten føjes til servlet-konteksten:

container.addListener (ny ContextLoaderListener (kontekst));

Det CXFServlet klasse, der er defineret af Apache CXF, genereres og registreres til at håndtere indgående anmodninger:

ServletRegistration.Dynamic dispatcher = container.addServlet ("dispatcher", ny CXFServlet ());

Applikationskonteksten indlæser fjederelementer, der er defineret i en konfigurationsfil. I dette tilfælde er navnet på servlet cxfderfor ser konteksten efter disse elementer i en fil med navnet cxf-servlet.xml som standard.

Endelig kortlægges CXF-servlet til en relativ URL:

dispatcher.addMapping ("/ services");

3.2. Den gode gamle web.xml

Alternativt, hvis vi ønsker at bruge en (noget gammeldags) implementeringsbeskrivelse snarere end WebApplicationInitilizer interface, det tilsvarende web.xml filen skal indeholde følgende servletdefinitioner:

 cxf org.apache.cxf.transport.servlet.CXFServlet 1 cxf / services / * 

3.3. ServiceConfiguration Klasse

Lad os nu se på servicekonfigurationen - først et grundlæggende skelet, der omslutter bønnedefinitioner til webservicens slutpunkt:

@Configuration offentlig klasse ServiceConfiguration {// Bean definitioner}

Den første krævede bønne er SpringBus - som leverer udvidelser til Apache CXF til at arbejde med Spring Framework:

@Bean offentlig SpringBus springBus () {returner ny SpringBus (); }

En EnpointImpl bønne skal også oprettes ved hjælp af SpringBus bønne og en webservice implementator. Denne bønne bruges til at offentliggøre slutpunktet ved den givne HTTP-adresse:

@Bean public Endpoint endpoint () {EndpointImpl endpoint = new EndpointImpl (springBus (), new BaeldungImpl ()); endpoint.publish ("// localhost: 8080 / services / baeldung"); returner slutpunkt; }

Det BaeldungImpl klasse bruges til at implementere webservicegrænsefladen. Definitionen er angivet i det næste underafsnit.

Alternativt kan vi også erklære serverens slutpunkt i en XML-konfigurationsfil. Specifikt den cxf-servlet.xml filen nedenfor fungerer med web.xml implementeringsbeskrivelse som defineret i underafsnit 3.1 og beskriver det nøjagtige samme slutpunkt:

Bemærk, at XML-konfigurationsfilen er opkaldt efter det servletnavn, der er defineret i installationsbeskrivelsen, hvilket er cxf.

3.4. Type Definitioner

Næste - her er definitionen af implementator der allerede er nævnt i foregående underafsnit:

@WebService (endpointInterface = "com.baeldung.cxf.spring.Baeldung") offentlig klasse BaeldungImpl implementerer Baeldung {privat int-tæller; public String hej (String name) {return "Hello" + name + "!"; } offentligt strengregister (studerende) {counter ++; returner student.getName () + "er registreret elevnummer" + tæller; }}

Denne klasse giver en implementering af Baeldung slutpunktsgrænseflade, som Apache CXF vil inkludere i de offentliggjorte WSDL-metadata:

@WebService offentlig grænseflade Baeldung {String hej (String name); Stringregister (studerende) }

Både slutpunktsgrænsefladen såvel som implementator gøre brug af Studerende klasse, der er defineret som følger:

offentlig klasse studerende {privat strengnavn; // konstruktører, getters og settere}

4. Bønner på klientsiden

For at drage fordel af Spring Framework erklærer vi en bønne i en @Konfiguration kommenteret klasse:

@Configuration public class ClientConfiguration {// Bean definitioner}

En bønne med navnet klient er defineret:

@Bean (name = "client") offentligt objekt generereProxy () {returner proxyFactoryBean (). Opret (); }

Det klient bønne repræsenterer en proxy for Baeldung webservice. Det er skabt ved en påkaldelse til skab metode på en JaxWsProxyFactoryBean bean, en fabrik til oprettelse af JAX-WS-proxyer.

Det JaxWsProxyFactoryBean objekt oprettes og konfigureres efter følgende metode:

@Bean offentlig JaxWsProxyFactoryBean proxyFactoryBean () {JaxWsProxyFactoryBean proxyFactory = ny JaxWsProxyFactoryBean (); proxyFactory.setServiceClass (Baeldung.class); proxyFactory.setAddress ("// localhost: 8080 / services / baeldung"); returnere proxyFactory; }

Fabrikken serviceClass egenskab betegner webtjenestegrænsefladen, mens adresse egenskab angiver URL-adressen for proxyen til at foretage fjernopkald.

Også for Spring bønner på klientsiden kan man vende tilbage til en XML-konfigurationsfil. Følgende elementer erklærer de samme bønner som dem, vi lige har programmeret konfigureret ovenfor:

5. Test tilfælde

Dette afsnit beskriver testsager, der bruges til at illustrere Apache CXF support til Spring. Testcases er defineret i en klasse, der er navngivet StudentTest.

Først skal vi indlæse en Spring-applikationskontekst fra ovennævnte ServiceConfiguration konfigurationsklasse og cache den i sammenhæng Mark:

privat ApplicationContext context = ny AnnotationConfigApplicationContext (ClientConfiguration.class);

Derefter erklæres en proxy til serviceendepunktsgrænsefladen og indlæses fra applikationskonteksten:

privat Baeldung baeldungProxy = (Baeldung) context.getBean ("klient");

Det her Baeldung proxy vil blive brugt i testsager beskrevet nedenfor.

I det første test tilfælde beviser vi, at når Hej metode kaldes lokalt på proxyen, svaret er nøjagtigt det samme som hvad slutpunktet implementator vender tilbage fra den eksterne webtjeneste:

@Test offentlig ugyldig nårUsingHelloMethod_thenCorrect () {String response = baeldungProxy.hello ("John Doe"); assertEquals ("Hej John Doe!", svar); }

I det andet testtilfælde tilmelder studerende sig til Baeldung-kurser ved lokalt at påberåbe sig Tilmeld metode på proxyen, som igen kalder webservicen. Denne fjerntjeneste beregner derefter elevnumrene og returnerer dem til den, der ringer op. Følgende kodestykke bekræfter, hvad vi forventer:

@Test offentlig ugyldig nårUsingRegisterMethod_thenCorrect () {Student student1 = ny studerende ("Adam"); Studerende student2 = ny studerende ("Eve"); String student1Response = baeldungProxy.register (student1); String student2Response = baeldungProxy.register (student2); assertEquals ("Adam er registreret studerende nummer 1", student1Response); assertEquals ("Eve er registreret studerende nummer 2", student2Response); }

6. Integrationstest

For at blive implementeret som en webapplikation på en server, skal kodestykker i denne vejledning først pakkes ind i en WAR-fil. Dette kan opnås ved at erklære emballage egenskab i POM-filen:

krig

Emballagejobbet implementeres af Maven WAR-pluginet:

 maven-war-plugin 2.6 false 

Dette plugin pakker den kompilerede kildekode i en WAR-fil. Da vi konfigurerer servletkonteksten ved hjælp af Java-kode, er den traditionelle web.xml implementeringsbeskrivelse behøver ikke at eksistere. Som et resultat, den failOnMissingWebXml ejendom skal indstilles til falsk for at undgå fejl, når pluginet udføres.

Vi kan følge dette link for den nyeste version af Maven WAR plugin.

For at illustrere driften af ​​webservicen opretter vi en integrationstest. Denne test genererer først en WAR-fil og starter en integreret server, får klienter til at påkalde webservicen, verificerer efterfølgende svar og stopper endelig serveren.

Følgende plugins skal inkluderes i Maven POM-filen. For flere detaljer, se denne Integration Testing tutorial.

Her er Maven Surefire-pluginet:

 maven-surefire-plugin 2.19.1 StudentTest.java 

Den seneste version af dette plugin kan findes her.

EN profil sektion med id af integration erklæres for at lette integrationstesten:

  integration ... 

Maven Cargo plugin er inkluderet i integration profil:

 org.codehaus.cargo cargo-maven2-plugin 1.5.0 jetty9x integreret localhost 8080 start-server pre-integration-test start stop-server post-integration-test stop 

Bemærk, at last.hostnavn og cargo.servlet.port konfigurationsegenskaber er kun inkluderet af hensyn til klarheden. Disse konfigurationsegenskaber kan udelades uden nogen indflydelse på applikationen, da deres værdier er de samme som standardværdierne. Dette plugin starter serveren, venter på forbindelser og stopper endelig serveren for at frigive systemressourcer.

Dette link giver os mulighed for at tjekke den nyeste version af Maven Cargo plugin.

Maven Surefire-pluginet erklæres igen inden for integration profil for at tilsidesætte dens konfiguration i hovedsagen bygge sektion og til at udføre testsager beskrevet i det foregående afsnit:

 maven-surefire-plugin 2.19.1 integration-test test ingen 

Nu kan hele processen køres med kommandoen: mvn -Pintegration ren installation.

7. Konklusion

Denne tutorial illustrerede Apache CXF support til Spring. Især er det blevet vist, hvordan en webtjeneste kan offentliggøres ved hjælp af en Spring-konfigurationsfil, og hvordan en klient kan interagere med denne service gennem en proxy oprettet af en Apache CXF-proxyfabrik, som blev erklæret i en anden konfigurationsfil.

Implementeringen af ​​alle disse eksempler og kodestykker findes i det sammenkædede GitHub-projekt.