En guide til Apache CXF med våren

1. Oversikt

Denne opplæringen fokuserer på konfigurering og bruker Apache CXF-rammeverket sammen med Spring - enten med Java- eller XML-konfigurasjon.

Det er den andre i en serie om Apache CXF; den første fokuserte på grunnleggende CXF som en implementering av JAX-WS standard APIer.

2. Maven-avhengigheter

I likhet med forrige opplæring, må følgende to avhengigheter inkluderes:

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

For de nyeste versjonene av Apache CXF-gjenstander, sjekk ut apache-cxf.

I tillegg er følgende avhengigheter nødvendig for å støtte våren:

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

De siste versjonene av vårartefakter finner du her.

Til slutt, fordi vi programmatisk konfigurerer applikasjonen ved hjelp av Java Servlet 3.0+ API i stedet for en tradisjonell web.xml distribusjonsbeskrivelse, trenger vi gjenstanden nedenfor:

 javax.servlet javax.servlet-api 3.1.0 

Det er her vi kan finne den nyeste versjonen av Servlet API.

3. Komponenter på serversiden

La oss nå se på komponentene som må være til stede på serversiden for å publisere endepunktet for nettjenesten.

3.1. WebApplicationInitilizer Grensesnitt

De WebApplicationInitializer grensesnitt er implementert for å programmatisk konfigurere ServletContext grensesnitt for applikasjonen. Når det er til stede på klassestien, er det ved oppstart metoden blir automatisk påkalt av servletbeholderen og deretter ServletContext initieres og initialiseres.

Her er hvordan en klasse er definert for å implementere WebApplicationInitializer grensesnitt:

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

De ved oppstart() metoden er implementert ved hjelp av kodebiter vist nedenfor.

Først opprettes og konfigureres en Spring-applikasjonskontekst for å registrere en klasse som inneholder konfigurasjonsmetadata:

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

De ServiceConfiguration klassen er kommentert med @Konfigurasjon kommentar for å gi bønnedefinisjoner. Denne klassen blir diskutert i neste underavsnitt.

Følgende tekstutdrag viser hvordan vårapplikasjonskonteksten legges til servletkonteksten:

container.addListener (ny ContextLoaderListener (kontekst));

De CXFServlet klasse, som er definert av Apache CXF, genereres og registreres for å håndtere innkommende forespørsler:

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

Applikasjonskonteksten laster inn fjærelementer som er definert i en konfigurasjonsfil. I dette tilfellet er navnet på servetten cxfDerfor ser konteksten etter elementene i en fil som heter cxf-servlet.xml som standard.

Til slutt blir CXF-servletten tilordnet en relativ URL:

dispatcher.addMapping ("/ services");

3.2. Den gode gamle web.xml

Alternativt, hvis vi vil bruke en (noe gammeldags) distribusjonsbeskrivelse i stedet for WebApplicationInitilizer grensesnitt, det tilsvarende web.xml filen skal inneholde følgende servletdefinisjoner:

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

3.3. ServiceConfiguration Klasse

La oss nå ta en titt på tjenestekonfigurasjonen - først et grunnleggende skjelett som vedlegger bønnedefinisjoner for nettjenestens sluttpunkt:

@Configuration public class ServiceConfiguration {// Bean definitions}

Den første nødvendige bønnen er SpringBus - som leverer utvidelser for Apache CXF for å jobbe med Spring Framework:

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

An EnpointImpl bønne må også opprettes ved hjelp av SpringBus bønne og en nettjeneste implementator. Denne bønnen brukes til å publisere sluttpunktet på den gitte HTTP-adressen:

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

De BaeldungImpl klasse brukes til å implementere nettjenestegrensesnittet. Definisjonen er gitt i neste underavsnitt.

Alternativt kan vi også erklære serverens endepunkt i en XML-konfigurasjonsfil. Spesielt, den cxf-servlet.xml filen nedenfor fungerer med web.xml distribusjonsbeskrivelse som definert i underavsnitt 3.1 og beskriver nøyaktig samme endepunkt:

Merk at XML-konfigurasjonsfilen er oppkalt etter servlettnavnet som er definert i distribusjonsbeskrivelsen cxf.

3.4. Type definisjoner

Neste - her er definisjonen av implementator som allerede er nevnt i forrige underavsnitt:

@WebService (endpointInterface = "com.baeldung.cxf.spring.Baeldung") offentlig klasse BaeldungImpl implementerer Baeldung {private int counter; public String hei (String name) {return "Hello" + name + "!"; } offentlig strengregister (studentstudent) {counter ++; returner student.getName () + "er registrert studentnummer" + teller; }}

Denne klassen gir en implementering for Baeldung endepunktgrensesnitt som Apache CXF vil inkludere i de publiserte WSDL-metadataene:

@WebService offentlig grensesnitt Baeldung {streng hei (strengnavn); Strenkeregister (Studentstudent); }

Både sluttpunktsgrensesnittet samt implementator gjøre bruk av Student klasse, som er definert som følger:

offentlig klasse Student {privat Strengnavn; // konstruktører, getters og setters}

4. Bønner på klientsiden

For å dra nytte av Spring Framework, erklærer vi en bønne i en @Konfigurasjon kommentert klasse:

@Configuration public class ClientConfiguration {// Bean definitions}

En bønne med navnet klient er definert:

@Bean (name = "client") offentlig Object generereProxy () {retur proxyFactoryBean (). Opprette (); }

De klient bønne representerer en fullmektig for Baeldung nettjeneste. Det er skapt av en påkallelse til skape metode på en JaxWsProxyFactoryBean bean, en fabrikk for opprettelse av JAX-WS-fullmakter.

De JaxWsProxyFactoryBean objektet opprettes og konfigureres etter følgende metode:

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

Fabrikken serviceClass egenskap betegner nettjenestegrensesnittet, mens adresse egenskap angir URL-adressen til proxyen for å foreta eksterne påkallinger.

Også for vårbønner på klientsiden kan man gå tilbake til en XML-konfigurasjonsfil. Følgende elementer erklærer de samme bønnene som de vi nettopp har konfigurert ovenfor:

5. Test tilfeller

Denne delen beskriver testtilfeller som brukes til å illustrere Apache CXF-støtte for våren. Testtilfellene er definert i en klasse som heter StudentTest.

Først må vi laste inn en vårapplikasjonskontekst fra det ovennevnte ServiceConfiguration konfigurasjonsklasse og cache den i kontekst felt:

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

Deretter blir en proxy for tjenestens endepunktsgrensesnitt erklært og lastet fra applikasjonskonteksten:

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

Dette Baeldung fullmektig vil bli brukt i testsaker beskrevet nedenfor.

I den første prøvesaken viser vi at når Hallo metoden blir lokalt påkalt på proxyen, er svaret nøyaktig det samme som endepunktet implementator returnerer fra den eksterne nettjenesten:

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

I den andre prøvesaken registrerer studentene seg på Baeldung-kurs ved å lokalt påkalle registrere metode på proxyen, som igjen kaller nettjenesten. Den eksterne tjenesten vil da beregne studentnumrene og returnere dem til den som ringer. Følgende kodebit bekrefter hva vi forventer:

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

6. Integrasjonstesting

For å kunne distribueres som et webapplikasjon på en server, må kodebiter i denne opplæringen pakkes inn i en WAR-fil først. Dette kan oppnås ved å erklære emballasje egenskap i POM-filen:

krig

Emballasjjobben er implementert av Maven WAR plugin:

 maven-war-plugin 2.6 false 

Dette pluginet pakker den kompilerte kildekoden i en WAR-fil. Siden vi konfigurerer servletkonteksten ved hjelp av Java-kode, er det tradisjonelle web.xml distribusjonsbeskrivelse trenger ikke å eksistere. Som et resultat ble den failOnMissingWebXml eiendommen må settes til falsk for å unngå feil når programtillegget kjøres.

Vi kan følge denne lenken for den nyeste versjonen av Maven WAR-plugin.

For å illustrere driften av nettjenesten lager vi en integrasjonstest. Denne testen genererer først en WAR-fil og starter en innebygd server, får klienter til å påkalle webtjenesten, verifiserer påfølgende svar og til slutt stopper serveren.

Følgende plugins må inkluderes i Maven POM-filen. For mer informasjon, vennligst sjekk ut denne veiledningen for integrasjonstesting.

Her er Maven Surefire-plugin:

 maven-surefire-plugin 2.19.1 StudentTest.java 

Den siste versjonen av dette pluginet finner du her.

EN profil seksjon med id av integrering er erklært for å lette integrasjonstesten:

  integrering ... 

Pluggen Maven Cargo er inkludert i integrering profil:

 org.codehaus.cargo cargo-maven2-plugin 1.5.0 jetty9x innebygd localhost 8080 start-server pre-integrasjon-test start stopp-server post-integrasjon-test stopp 

Merk at last.hostnavn og last.servlet.port konfigurasjonsegenskaper er bare inkludert for klarhets skyld. Disse konfigurasjonsegenskapene kan utelates uten at det påvirker applikasjonen siden verdiene er de samme som standardverdiene. Dette pluginet starter serveren, venter på tilkoblinger og stopper til slutt serveren for å frigjøre systemressurser.

Denne lenken lar oss sjekke ut den nyeste versjonen av Maven Cargo-plugin.

Maven Surefire-pluginet blir erklært igjen, innenfor integrering profil, for å overstyre konfigurasjonen i hovedsak bygge seksjonen og for å utføre testsaker beskrevet i forrige avsnitt:

 maven-surefire-plugin 2.19.1 integrasjon-test test ingen 

Nå kan hele prosessen kjøres med kommandoen: mvn -Installasjon ren installasjon.

7. Konklusjon

Denne opplæringen illustrerte Apache CXF-støtte for våren. Spesielt har det blitt vist hvordan en webtjeneste kan publiseres ved hjelp av en Spring-konfigurasjonsfil, og hvordan en klient kan samhandle med denne tjenesten gjennom en proxy opprettet av en Apache CXF proxy-fabrikk, som ble erklært i en annen konfigurasjonsfil.

Implementeringen av alle disse eksemplene og kodebiter finner du i det tilknyttede GitHub-prosjektet.