Memanggil Layanan Web SOAP di Java

1. Ikhtisar

Dalam tutorial ini, kita akan belajar bagaimana membangun klien SOAP di Java dengan JAX-WS RI . Pertama, kami akan membuat kode klien menggunakan utilitas wsimport , dan kemudian mengujinya menggunakan JUnit.

Bagi mereka yang baru memulai, pengenalan kami ke JAX-WS memberikan latar belakang yang bagus tentang subjek tersebut.

2. Layanan Web

Sebelum kita mulai membangun klien, kita membutuhkan server. Dalam kasus ini, server mengekspos layanan web JAX-WS.

Untuk keperluan tutorial ini, kita akan menggunakan layanan web yang akan mengambilkan kita data suatu negara, berdasarkan namanya.

2.1. Ringkasan Implementasi

Karena kami berfokus pada membangun klien, kami tidak akan membahas detail implementasi layanan kami.

Mari kita cukup untuk mengatakan bahwa CountryService antarmuka digunakan untuk mengekspos layanan web ke dunia luar. Untuk menyederhanakannya, kami akan membangun dan menerapkan layanan web menggunakan javax.xml.ws.Endpoint API di kelas CountryServicePublisher kami .

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

Setelah memulai server, menekan URL // localhost: 8888 / ws / country? Wsdl memberi kita file deskripsi layanan web. WSDL bertindak sebagai panduan untuk memahami penawaran layanan dan menghasilkan kode implementasi untuk klien.

2.2. Bahasa Deskripsi Layanan Web

Mari kita lihat WSDL layanan web kami, negara :


    

Singkatnya, ini adalah informasi berguna yang diberikannya:

  • kita bisa memanggil metode findByName dengan argumen string
  • sebagai tanggapan, layanan akan mengembalikan kepada kami jenis negara khusus
  • jenis didefinisikan dalam skema xsd yang dihasilkan di lokasi // localhost: 8888 / ws / country? xsd = 1 :

    

Itu saja yang kita butuhkan untuk menerapkan klien.

Mari kita lihat caranya di bagian selanjutnya.

3. Menggunakan wsimport untuk Menghasilkan Kode Klien

3.1. Plugin Maven

Pertama, mari tambahkan plugin ke pom.xml kita 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 jalankan plugin ini:

mvn clean jaxws:wsimport

Itu saja! Perintah di atas akan menghasilkan kode dalam paket yang ditentukan com.baeldung.soap.ws.client.generated di dalam sourceDestDir yang kami sediakan dalam konfigurasi plugin.

Cara lain untuk mencapai hal yang sama adalah dengan menggunakan utilitas wsimport . Itu keluar dari kotak dengan distribusi JDK 8 standar dan dapat ditemukan di bawah direktori JAVA_HOME / bin .

Untuk menghasilkan kode klien menggunakan wsimport , kita dapat menavigasi ke root proyek, 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 bahwa titik akhir layanan harus tersedia agar plugin atau perintah berhasil dijalankan.

Selanjutnya, mari kita lihat artefak yang dihasilkan.

3.2. POJO yang dihasilkan

Berdasarkan xsd yang kita lihat sebelumnya, alat akan menghasilkan file 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 bisa kita lihat, kelas yang dihasilkan dihiasi dengan anotasi JAXB untuk menyusun dan melepaskan objek ke dan dari XML.

Juga, ini menghasilkan enum Mata Uang :

@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. CountryService

Artefak yang dihasilkan kedua adalah antarmuka yang bertindak sebagai proxy ke layanan web sebenarnya.

Antarmuka CountryService mendeklarasikan metode yang sama seperti server 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); }

Khususnya, antarmuka ditandai sebagai javax.jws.WebService , dengan SOAPBinding.Style sebagai RPC seperti yang didefinisikan oleh WSDL layanan.

Metode findByName dianotasi untuk menyatakan bahwa itu adalah javax.jws.WebMethod , dengan jenis parameter masukan dan keluaran yang diharapkan.

3.4. CountryServiceImplService

Kelas kami yang dihasilkan berikutnya, CountryServiceImplService , memperluas javax.xml.ws.Service. Anotasinya WebServiceClient menunjukkan bahwa itu adalah tampilan klien dari suatu layanan:

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

Metode penting yang perlu diperhatikan di sini adalah getCountryServiceImplPort . Diberikan nama yang memenuhi syarat dari titik akhir layanan, atau QName , dan nama antarmuka titik akhir layanan proxy dinamis, ia mengembalikan contoh proxy.

Untuk menjalankan layanan web, kita perlu menggunakan proxy ini, seperti yang akan kita lihat sebentar lagi .

Using a proxy makes it seem as if we are calling a service locally, abstracting away the intricacies of remote invocation.

4. Testing the Client

Next, we'll write a JUnit test to connect to the web service using the generated client code.

Before we can do that, we need to get the service's proxy instance at the client end:

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

For more advanced scenarios such as enabling or disabling a WebServiceFeature, we can use other generated constructors for CountryServiceImplService.

Now let's look at some tests:

@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 bisa kita lihat, memanggil metode layanan jarak jauh menjadi sesederhana memanggil metode secara lokal. Metode findByName proxy mengembalikan instance Negara yang cocok dengan nama yang kami berikan. Kemudian, kami menggunakan berbagai pengambil POJO untuk menegaskan nilai yang diharapkan.

5. Kesimpulan

Dalam tutorial ini, kami melihat cara memanggil layanan web SOAP di Java menggunakan JAX-WS RI dan utilitas wsimport .

Alternatifnya, kita dapat menggunakan implementasi JAX-WS lain seperti Apache CXF, Apache Axis2, dan Spring untuk melakukan hal yang sama.

Seperti biasa, kode sumber tersedia di GitHub.