Membuat Perkhidmatan Web SOAP dengan Spring

1. Gambaran keseluruhan

Dalam tutorial ini, kita akan melihat cara membuat perkhidmatan web berasaskan SOAP dengan Spring Web Starter Web Services.

2. Perkhidmatan Web SOAP

Perkhidmatan web, ringkasnya, mesin ke mesin, perkhidmatan bebas platform yang membolehkan komunikasi melalui rangkaian.

SOAP adalah protokol pesanan. Mesej (permintaan dan respons) adalah dokumen XML melalui HTTP . Kontrak XML ditentukan oleh WSDL (Bahasa Penerangan Perkhidmatan Web). Ini menyediakan sekumpulan aturan untuk menentukan pesan, pengikatan, operasi, dan lokasi layanan.

XML yang digunakan dalam SOAP boleh menjadi sangat kompleks. Atas sebab ini, lebih baik menggunakan SOAP dengan rangka seperti JAX-WS atau Spring, seperti yang akan kita lihat dalam tutorial ini.

3. Gaya Pembangunan Pertama-Kontrak

Terdapat dua kemungkinan pendekatan semasa membuat perkhidmatan web: Kontrak-Terakhir dan Kontrak-Pertama. Apabila kita menggunakan pendekatan kontrak-terakhir, kita mulai dengan kod Java, dan kita menghasilkan kontrak perkhidmatan web (WSDL) dari kelas. Semasa menggunakan kontrak-pertama, kita mulakan dengan kontrak WSDL, dari mana kita menghasilkan kelas Java.

Spring-WS hanya menyokong gaya pembangunan kontrak-pertama.

4. Menyiapkan Projek Spring Boot

Kami akan membuat projek Spring Boot di mana kami akan menentukan pelayan SOAP WS kami.

4.1. Ketergantungan Maven

Mari mulakan dengan menambahkan spring-boot-starter-parent ke projek kami:

 org.springframework.boot spring-boot-starter-parent 2.2.6.RELEASE  

Seterusnya, mari kita tambahkan pergantungan spring-boot-starter-web- service dan wsdl4j :

 org.springframework.boot spring-boot-starter-web-services   wsdl4j wsdl4j  

4.2. Fail XSD

Pendekatan kontrak pertama menghendaki kami membuat domain (kaedah dan parameter) untuk perkhidmatan kami terlebih dahulu. Kami akan menggunakan fail skema XML (XSD) yang Spring-WS akan eksport secara automatik sebagai WSDL:

Dalam fail ini, kita melihat format permintaan perkhidmatan web getCountryRequest . Kami menentukannya untuk menerima satu parameter rentetan jenis .

Seterusnya, kami menentukan format respons, yang mengandungi objek negara jenis .

Akhirnya, kita melihat objek mata wang , digunakan dalam objek negara .

4.3. Hasilkan Kelas Java Domain

Kami sekarang akan menghasilkan kelas Java dari fail XSD yang ditentukan dalam bahagian sebelumnya. The jaxb2-Maven-plugin akan melakukannya secara automatik semasa masa membina. Plugin menggunakan alat XJC sebagai enjin penjanaan kod. XJC menyusun fail skema XSD ke dalam kelas Java yang diberi penjelasan penuh.

Mari tambah dan konfigurasikan pemalam di pom.xml kami:

 org.codehaus.mojo jaxb2-maven-plugin 1.6   xjc  xjc     ${project.basedir}/src/main/resources/ ${project.basedir}/src/main/java false   

Di sini kita perhatikan dua konfigurasi penting:

  • $ {project.basedir} / src / main / resources - Lokasi fail XSD
  • $ {project.basedir} / src / main / java - Di mana kita mahu kod Java kita dihasilkan

Untuk menghasilkan kelas Java, kita hanya dapat menggunakan alat xjc dari pemasangan Java kita. Walaupun dalam projek Maven kami perkara lebih mudah, kerana kelas akan dihasilkan secara automatik semasa pembuatan Maven biasa:

mvn compile

4.4. Tambahkan Titik Akhir Perkhidmatan Web SOAP

Kelas titik akhir perkhidmatan web SOAP akan menangani semua permintaan masuk untuk perkhidmatan tersebut. Ini akan memulakan pemprosesan dan akan menghantar balasan kembali.

Sebelum menentukan ini, kami membuat repositori Negara untuk memberikan data ke perkhidmatan web.

@Component public class CountryRepository { private static final Map countries = new HashMap(); @PostConstruct public void initData() { // initialize countries map } public Country findCountry(String name) { return countries.get(name); } } 

Seterusnya, mari kita konfigurasikan titik akhir:

@Endpoint public class CountryEndpoint { private static final String NAMESPACE_URI = "//www.baeldung.com/springsoap/gen"; private CountryRepository countryRepository; @Autowired public CountryEndpoint(CountryRepository countryRepository) { this.countryRepository = countryRepository; } @PayloadRoot(namespace = NAMESPACE_URI, localPart = "getCountryRequest") @ResponsePayload public GetCountryResponse getCountry(@RequestPayload GetCountryRequest request) { GetCountryResponse response = new GetCountryResponse(); response.setCountry(countryRepository.findCountry(request.getName())); return response; } } 

Berikut adalah beberapa perincian yang perlu diperhatikan:

  • @Endpoint - mendaftarkan kelas dengan Spring WS sebagai Endpoint Perkhidmatan Web
  • @PayloadRoot - mentakrifkan kaedah pengendali mengikut atribut namespace dan localPart
  • @ResponsePayload - menunjukkan bahawa kaedah ini mengembalikan nilai yang akan dipetakan ke muatan respons
  • @RequestPayload - menunjukkan bahawa kaedah ini menerima parameter yang akan dipetakan dari permintaan masuk

4.5. Kacang Konfigurasi Perkhidmatan Web SOAP

Mari sekarang buat kelas untuk mengkonfigurasi servlet penghantar mesej Spring untuk menerima permintaan:

@EnableWs @Configuration public class WebServiceConfig extends WsConfigurerAdapter { // bean definitions }

@EnableWs membolehkan ciri-ciri Perkhidmatan Web SOAP dalam aplikasi Spring Boot ini. The WebServiceConfig kelas memanjangkan WsConfigurerAdapter kelas asas, yang mengkonfigurasi Spring-WS model pengaturcaraan anotasi yang dipacu.

Let's create a MessageDispatcherServlet which is used for handling SOAP requests:

@Bean public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) { MessageDispatcherServlet servlet = new MessageDispatcherServlet(); servlet.setApplicationContext(applicationContext); servlet.setTransformWsdlLocations(true); return new ServletRegistrationBean(servlet, "/ws/*"); } 

We set the injected ApplicationContext object of the servlet so that Spring-WS can find other Spring beans.

We also enable the WSDL location servlet transformation. This transforms the location attribute of soap:address in the WSDL so that it reflects the URL of the incoming request.

Finally, let's create a DefaultWsdl11Definition object. This exposes a standard WSDL 1.1 using an XsdSchema. The WSDL name will be the same as the bean name.

@Bean(name = "countries") public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema countriesSchema) { DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition(); wsdl11Definition.setPortTypeName("CountriesPort"); wsdl11Definition.setLocationUri("/ws"); wsdl11Definition.setTargetNamespace("//www.baeldung.com/springsoap/gen"); wsdl11Definition.setSchema(countriesSchema); return wsdl11Definition; } @Bean public XsdSchema countriesSchema() { return new SimpleXsdSchema(new ClassPathResource("countries.xsd")); } 

5. Testing the SOAP Project

Once the project configuration has been completed, we're ready to test it.

5.1. Build and Run the Project

It would be possible to create a WAR file and deploy it to an external application server. We'll instead use Spring Boot, which is a faster and easier way to get the application up and running.

First, we add the following class to make the application executable:

@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } 

Notice that we're not using any XML files (like web.xml) to create this application. It's all pure Java.

Now we're ready to build and run the application:

mvn spring-boot:run

To check if the application is running properly, we can open the WSDL through the URL: //localhost:8080/ws/countries.wsdl

5.2. Test a SOAP Request

To test a request, we create the following file and name it request.xml:

    Spain    

To send the request to our test server, we could use external tools like SoapUI or the Google Chrome extension Wizdler. Another way is to run the following command in our shell:

curl --header "content-type: text/xml" -d @request.xml //localhost:8080/ws

Respons yang dihasilkan mungkin tidak mudah dibaca tanpa lekukan atau putaran baris.

Untuk melihatnya diformat, kita boleh menyalin tampal ke IDE atau alat lain. Sekiranya kita memasang xmllib2, kita dapat mengeluarkan output perintah curl kita ke xmllint :

curl [command-line-options] | xmllint --format -

Respons tersebut mesti mengandungi maklumat mengenai Sepanyol:

     Spain 46704314 Madrid EUR     

6. Kesimpulannya

Dalam artikel ini, kami belajar bagaimana membuat perkhidmatan web SOAP menggunakan Spring Boot. Kami juga belajar bagaimana menghasilkan kod Java dari fail XSD, dan kami melihat bagaimana mengkonfigurasi kacang Spring yang diperlukan untuk memproses permintaan SOAP.

Kod sumber lengkap boleh didapati di GitHub.