สร้าง SOAP Web Service ด้วย Spring Boot
ถ้าพูดถึง SOAP แล้ว หลายคนจะบอกว่าเป็นเทคโนโลยีเก่าถ้าเทียบกับ REST ในการสร้าง web service หรือ Microservice API แต่หลายหน่วยงานก็ยังมีการใช้งาน SOAP อยู่ ดังนั้นการลองสร้าง SOAP web service ด้วย Spring Boot ก็จะทำให้เข้าใจมากขึ้น โดยอ้างอิงจาก Spring Guide
SOAP คืออะไร
Simple Object Access Protocol เป็นโพรโตคอลรูปแบบของการออกแบบโมเดลการสื่อสารในลักษณะของการกระจาย ในการติดต่อสื่อสารที่มีตัวกลาง โดยใช้ XML Information Set และขึ้นอยู่กับ Application layer อย่างเช่น HTTP หรือ SMTP ซึ่งมาตรฐานของ SOAP กำหนดโดย W3C
SOAP มี Messaging Protocol layer โครงสร้างประกอบด้วย 3 ส่วน
- Envelope กำหนดโครงสร้างของ message และจำ process อย่างไร
- Set of encoding rule ของ application-define data type
- Convention เป็นตัวแทนของ procedure request หรือ response
<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:m="http://www.example.org">
<soap:Header>
</soap:Header>
<soap:Body>
<m:GetStockPrice>
<m:StockName>GOOG</m:StockName>
</m:GetStockPrice>
</soap:Body>
</soap:Envelope>
สร้าง Spring Boot project
สร้าง project ด้วย Spring Initializr โดยเลือก dependencies เป็น Web
และ Web Services
สำหรับ Spring WS
และเพิ่ม wsdl4j
dependency เข้าไปใน pom.xml
เพื่อใช้ WSDL4J เพื่อ creation, representation, manipulation เอกสารไฟล์ WSDL อ้างอิงมาตรฐาน JSR110
<dependency>
<groupId>wsdl4j</groupId>
<artifactId>wsdl4j</artifactId>
</dependency>
สร้าง XML schema
Web Service domain กำหนดในไพล์ XML schema (XSD) ที่ Spring-WS จะ export ไปเป็น WSDL โดยอัตโนมัติ
ในไพล์ XSD จะกำหนด name, population, capital และ currency ของ Country
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://iphayao.com/producing-web-service"
targetNamespace="http://iphayao.com/producing-web-service" elementFormDefault="qualified">
<xs:element name="getCountryRequest">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="getCountryResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="country" type="tns:country"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="country">
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="population" type="xs:int"/>
<xs:element name="capital" type="xs:string"/>
<xs:element name="currency" type="tns:currency"/>
</xs:sequence>
</xs:complexType>
<xs:simpleType name="currency">
<xs:restriction base="xs:string">
<xs:enumeration value="GBP"/>
<xs:enumeration value="EUR"/>
<xs:enumeration value="PLN"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
สร้าง Domain class
ต่อไปเราจะสร้าง domain class จากไฟล์ XSD ซึ่งใช้วิธีการสร้างโดยอัตโนมัติระหว่าง build time ของ maven project (Spring project) โดยเพิ่ม plugin นี้เข้าไปในไฟล์ pom.xml
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<id>xjc</id>
<goals>
<goal>xjc</goal>
</goals>
</execution>
</executions>
<configuration>
<schemaDirectory>${project.basedir}/src/main/resources/ </schemaDirectory>
<outputDirectory>${project.basedir}/src/main/java </outputDirectory>
<clearOutputDir>false</clearOutputDir>
</configuration>
</plugin>
เมื่อเรา compile แล้วจะได้ domain class ใน directory producing_web_service
ซึ่งเราจะใช้ในภายหลัง
สร้าง Country Repository
เพื่อที่จให้ข้อมูลกับ web service ต้องสร้าง country respository โดยเป็น hardcode data (Map) ของประเทศต่างๆ ที่มี ชื่อประเทศ (Name), เมืองหลวง (Capital) และ หน่วยเงิน (Currency) ดังนี้
สร้าง Country Service endpoint
เพื่อสร้าง service endpoint ของ Country จำเป็นต้องใช้ POJO ด้วย Spring WS annotation เพื่อจัดการกับ SOAP request
@Endpoint
เป็นการลงทะเบียนคลาสกับ Spring WS สำหรับจัดการ SOAP request
@PayloadRoot
ใช้โดย Spring WS จัดการ method ขึ้นอยู่กับ namespace
และ localPart
ของ message
@RequestPayload
เป็นการกำหนดว่า message จะผูกเข้ากับ request
parameter
@ResponsePayload
ทำให้ Spring WS ผูก return value ของ response payload
สร้าง Config Web Service
กำหนด configuration ของ web service เพื่อสร้าง bean สำหร้บ Spring WS ด้วย @EnableWs
เพื่อใช้ Spring WS Configuration
MessageDispatcherServlet
เป็น bean ที่แยก Servlet สำหรับ Spring WS โดย inject ApplicationContext
เข้ามา และลงทะเบียน bean ด้วย path /ws/*
DefaultWsd11Defination
เป็น bean สำหรับกำหนดนิยามต่างๆให้กับ Spring WS กำหนดชื่อ bean เป็น countries
โดย inject XsdSchema จาก countriesSchema
bean ที่อ่านไฟล์ countries.xsd
ทดลองรัน SOAP Web Service
หลังจากที่เราได้สร้าง SOAP Web Service แล้วก็ทดลองรัน Spring Boot project ด้วยคำสั่ง mvn spring-boot:run
ถ้าทุกอย่างถูกต้องจะได้ดังนี้
ใช้ Postman เพื่อเรียกไปที่ SOAP Web Sevice endpoint ด้วย POST
method เลือก body type เป็น text/xml
และข้อมูลเป็น SOAP request getCountryRequest
และจะได้ SOAP response getCountryResponse
กลับมากเป็นรูปแบบ XML
ถ้าเลือก body type เป็น text/xml
ไม่ได้ก็ใส่หรือแก้ไข header Content-Type
เป็น text/xml
ตัวอย่าง request body
สรุป
หลังจากที่ลองสร้าง SOAP Web Service ด้วย Spring Boot และ Spring WS นั้นไม่ยากเลยด้วยพลังของ Spring framework ทำให้เราเพียงกำหนดไฟล์ XSD แล้วใช้สร้างคลาส domain ได้ด้วย WSDL4J นำมาใช้ใน Repository และ Endpoint ได้เลย และกำหนดค่า configuration สำหรับ Spring WS แล้วก็ run application ก็ได้ SOAP Web Service แบบง่ายๆ มาใช้งานเลย Cool!!!!