Memohon Perkhidmatan Web SOAP di Java

1. Gambaran keseluruhan

Dalam tutorial ini, kita akan belajar bagaimana membina klien SOAP di Java dengan JAX-WS RI . Pertama, kami akan menghasilkan kod pelanggan menggunakan utiliti wsimport , dan kemudian mengujinya menggunakan JUnit.

Bagi mereka yang memulakannya, pengenalan kami kepada JAX-WS memberikan latar belakang yang hebat mengenai perkara ini.

2. Perkhidmatan Web

Sebelum kita mula membina pelanggan, kita memerlukan pelayan. Dalam kes ini, pelayan yang mendedahkan perkhidmatan web JAX-WS.

Untuk tujuan tutorial ini, kami akan menggunakan perkhidmatan web yang akan mengambil data negara, berdasarkan namanya.

2.1. Ringkasan Pelaksanaan

Oleh kerana kami memfokuskan diri untuk membina klien, kami tidak akan mengetahui perincian pelaksanaan perkhidmatan kami.

Cukuplah untuk mengatakan bahawa antara muka CountryService digunakan untuk mendedahkan perkhidmatan web ke dunia luar. Untuk menjaga perkara yang mudah, kami akan membina dan menggunakan perkhidmatan web menggunakan javax.xml.ws.Endpoint API di dalam kelas kami CountryServicePublisher .

Kami akan menjalankan CountryServicePublisher sebagai aplikasi Java untuk menerbitkan titik akhir yang akan menerima permintaan masuk. Dengan kata lain, ini akan menjadi pelayan kami.

Setelah memulakan pelayan, tekan URL // localhost: 8888 / ws / country? Wsdl memberi kami fail perihalan perkhidmatan web. WSDL bertindak sebagai panduan untuk memahami penawaran perkhidmatan dan menghasilkan kod pelaksanaan untuk pelanggan.

2.2. Bahasa Penerangan Perkhidmatan Web

Mari lihat WSDL perkhidmatan web kami, negara :


    

Ringkasnya, ini adalah maklumat berguna yang diberikannya:

  • kita boleh menggunakan kaedah findByName dengan argumen rentetan
  • Sebagai tindak balas, perkhidmatan ini akan mengembalikan jenis negara khusus kepada kita
  • jenis didefinisikan dalam skema xsd yang dihasilkan di lokasi // localhost: 8888 / ws / country? xsd = 1 :

    

Itu sahaja yang kita perlukan untuk melaksanakan klien.

Mari lihat bagaimana di bahagian seterusnya.

3. Menggunakan wsimport untuk Menghasilkan Kod Pelanggan

3.1. Plugin Maven

Pertama, mari tambahkan pemalam ke pom.xml kami untuk menggunakan alat ini melalui Maven:

 org.codehaus.mojo jaxws-maven-plugin 2.6   wsimport-from-jdk  wsimport      //localhost:8888/ws/country?wsdl  true com.baeldung.soap.ws.client.generated src/main/java  

Kedua, mari kita laksanakan pemalam ini:

mvn clean jaxws:wsimport

Itu sahaja! Perintah di atas akan menghasilkan kod dalam paket yang ditentukan com.baeldung.soap.ws.client.g dihasilkan dalam sourceDestDir yang kami sediakan dalam konfigurasi pemalam.

Cara lain untuk mencapai yang sama adalah dengan menggunakan utiliti wsimport . Ia keluar dari kotak dengan pengedaran JDK 8 standard dan boleh didapati di bawah direktori JAVA_HOME / bin .

Untuk menghasilkan kod pelanggan menggunakan wsimport , kita dapat menavigasi ke akar projek, dan menjalankan perintah ini:

JAVA_HOME/bin/wsimport -s src/main/java/ -keep -p com.baeldung.soap.ws.client.generated "//localhost:8888/ws/country?wsdl"

Penting untuk diingat bahawa titik akhir perkhidmatan harus tersedia agar berjaya melaksanakan pemalam atau perintah.

Seterusnya, mari kita lihat artifak yang dihasilkan.

3.2. POJO yang dihasilkan

Berdasarkan xsd yang kita lihat sebelumnya, alat ini akan menghasilkan fail bernama Country.java :

@XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "country", propOrder = { "capital", "currency", "name", "population" }) public class Country { protected String capital; @XmlSchemaType(name = "string") protected Currency currency; protected String name; protected int population; // standard getters and setters }

Seperti yang dapat kita lihat, kelas yang dihasilkan dihiasi dengan anotasi JAXB untuk marshalling dan unmarshalling objek ke dan dari XML.

Juga, menghasilkan enum Mata Wang :

@XmlType(name = "currency") @XmlEnum public enum Currency { EUR, INR, USD; public String value() { return name(); } public static Currency fromValue(String v) { return valueOf(v); } }

3.3. Perkhidmatan Negara

Artefak yang dihasilkan kedua adalah antara muka yang bertindak sebagai proksi kepada perkhidmatan web sebenar.

Antaramuka CountryService menyatakan kaedah yang sama dengan pelayan kami, findByName :

@WebService(name = "CountryService", targetNamespace = "//server.ws.soap.baeldung.com/") @SOAPBinding(style = SOAPBinding.Style.RPC) @XmlSeeAlso({ ObjectFactory.class }) public interface CountryService { @WebMethod @WebResult(partName = "return") @Action(input = "//server.ws.soap.baeldung.com/CountryService/findByNameRequest", output = "//server.ws.soap.baeldung.com/CountryService/findByNameResponse") public Country findByName(@WebParam(name = "arg0", partName = "arg0") String arg0); }

Terutama, antara muka ditandai sebagai javax.jws.WebService , dengan SOAPBinding. Gaya sebagai RPC seperti yang ditentukan oleh WSDL perkhidmatan.

Kaedah findByName dijelaskan untuk menyatakan bahawa itu adalah kaedah javax.jws.Web , dengan jenis parameter input dan output yang diharapkan.

3.4. Perkhidmatan Negara

Kelas yang akan datang kami dihasilkan, CountryServiceImplService , memanjangkan javax.xml.ws.Service. WebServiceClient anotasinya menunjukkan bahawa ia adalah pandangan pelanggan terhadap perkhidmatan:

@WebServiceClient(name = "CountryServiceImplService", targetNamespace = "//server.ws.soap.baeldung.com/", wsdlLocation = "//localhost:8888/ws/country?wsdl") public class CountryServiceImplService extends Service { private final static URL COUNTRYSERVICEIMPLSERVICE_WSDL_LOCATION; private final static WebServiceException COUNTRYSERVICEIMPLSERVICE_EXCEPTION; private final static QName COUNTRYSERVICEIMPLSERVICE_QNAME = new QName("//server.ws.soap.baeldung.com/", "CountryServiceImplService"); static { URL url = null; WebServiceException e = null; try { url = new URL("//localhost:8888/ws/country?wsdl"); } catch (MalformedURLException ex) { e = new WebServiceException(ex); } COUNTRYSERVICEIMPLSERVICE_WSDL_LOCATION = url; COUNTRYSERVICEIMPLSERVICE_EXCEPTION = e; } public CountryServiceImplService() { super(__getWsdlLocation(), COUNTRYSERVICEIMPLSERVICE_QNAME); } // other constructors @WebEndpoint(name = "CountryServiceImplPort") public CountryService getCountryServiceImplPort() { return super.getPort(new QName("//server.ws.soap.baeldung.com/", "CountryServiceImplPort"), CountryService.class); } private static URL __getWsdlLocation() { if (COUNTRYSERVICEIMPLSERVICE_EXCEPTION != null) { throw COUNTRYSERVICEIMPLSERVICE_EXCEPTION; } return COUNTRYSERVICEIMPLSERVICE_WSDL_LOCATION; } }

Kaedah penting yang perlu diberi perhatian di sini ialah getCountryServiceImplPort . Memandangkan nama yang layak dari titik akhir perkhidmatan, atau QName , dan nama antara muka perkhidmatan akhir proksi dinamik, ia mengembalikan contoh proksi.

Untuk menggunakan perkhidmatan web, kita perlu menggunakan proksi ini, seperti yang akan kita lihat sebentar lagi .

Menggunakan proksi nampaknya seolah-olah kita memanggil perkhidmatan secara tempatan, mengabaikan selok-belok pemanggilan jarak jauh.

4. Menguji Pelanggan

Seterusnya, kami akan menulis ujian JUnit untuk menyambung ke perkhidmatan web menggunakan kod pelanggan yang dihasilkan.

Sebelum kita dapat melakukannya, kita perlu mendapatkan contoh proksi perkhidmatan di hujung pelanggan:

@BeforeClass public static void setup() { CountryServiceImplService service = new CountryServiceImplService(); CountryService countryService = service.getCountryServiceImplPort(); }

Untuk senario yang lebih maju seperti mengaktifkan atau mematikan WebServiceFeature , kita boleh menggunakan pembina lain yang dihasilkan untuk CountryServiceImplService .

Sekarang mari kita lihat beberapa ujian:

@Test public void givenCountryService_whenCountryIndia_thenCapitalIsNewDelhi() { assertEquals("New Delhi", countryService.findByName("India").getCapital()); } @Test public void givenCountryService_whenCountryFrance_thenPopulationCorrect() { assertEquals(66710000, countryService.findByName("France").getPopulation()); } @Test public void givenCountryService_whenCountryUSA_thenCurrencyUSD() { assertEquals(Currency.USD, countryService.findByName("USA").getCurrency()); } 

Seperti yang kita lihat, menggunakan kaedah perkhidmatan jarak jauh menjadi semudah kaedah memanggil secara tempatan. Kaedah findByName proksi mengembalikan contoh Negara yang sepadan dengan nama yang kami berikan. Kemudian, kami menggunakan pelbagai penerima POJO untuk menegaskan nilai yang diharapkan.

5. Kesimpulan

Dalam tutorial ini, kami melihat bagaimana menggunakan perkhidmatan web SOAP di Java menggunakan JAX-WS RI dan utiliti wsimport .

Sebagai alternatif, kita boleh menggunakan implementasi JAX-WS lain seperti Apache CXF, Apache Axis2, dan Spring untuk melakukan perkara yang sama.

Seperti biasa, kod sumber tersedia di GitHub.