Mình đã giới thiệu với các bạn cách expose SOAP Web Service sử dụng APIkit SOAP trong Mule 3, APIkit SOAP trong Mule 4 có sự khác biệt, từ cách mà chúng ta bỏ tập tin .wsdl cho đến cách mà chúng ta build response để trả về cho người dùng. Cụ thể như thế nào? Chúng ta hãy cùng nhau tìm hiểu ở bài viết này các bạn nhé!
Đầu tiên, mình sẽ tạo mới một Mule project để làm ví dụ:
Mình sẽ sử dụng tập tin hello.wsdl có nội dung như sau để làm ví dụ:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
<?xml version='1.0' encoding='UTF-8'?><wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://muleesbcxfsoapexpose.huongdanjava.com/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" name="HelloWorldServiceService" targetNamespace="http://muleesbcxfsoapexpose.huongdanjava.com/"> <wsdl:types> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://muleesbcxfsoapexpose.huongdanjava.com/" attributeFormDefault="unqualified" elementFormDefault="unqualified" targetNamespace="http://muleesbcxfsoapexpose.huongdanjava.com/"> <xs:element name="hello" type="tns:hello"/> <xs:element name="helloResponse" type="tns:helloResponse"/> <xs:complexType name="hello"> <xs:sequence> <xs:element name="name" type="xs:string"/> </xs:sequence> </xs:complexType> <xs:complexType name="helloResponse"> <xs:sequence> <xs:element name="result" type="xs:string"/> </xs:sequence> </xs:complexType> <xs:element name="clientId" nillable="true" type="xs:string"/> </xs:schema> </wsdl:types> <wsdl:message name="helloResponse"> <wsdl:part element="tns:helloResponse" name="result"> </wsdl:part> <wsdl:part element="tns:clientId" name="clientId"> </wsdl:part> </wsdl:message> <wsdl:message name="hello"> <wsdl:part element="tns:hello" name="parameters"> </wsdl:part> <wsdl:part element="tns:clientId" name="clientId"> </wsdl:part> </wsdl:message> <wsdl:portType name="HelloWorldService"> <wsdl:operation name="hello"> <wsdl:input message="tns:hello" name="hello"> </wsdl:input> <wsdl:output message="tns:helloResponse" name="helloResponse"> </wsdl:output> </wsdl:operation> </wsdl:portType> <wsdl:binding name="HelloWorldServiceServiceSoapBinding" type="tns:HelloWorldService"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name="hello"> <soap:operation soapAction="" style="document"/> <wsdl:input name="hello"> <soap:header message="tns:hello" part="clientId" use="literal"> </soap:header> <soap:body parts="parameters" use="literal"/> </wsdl:input> <wsdl:output name="helloResponse"> <soap:header message="tns:helloResponse" part="clientId" use="literal"> </soap:header> <soap:body parts="result" use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="HelloWorldServiceService"> <wsdl:port binding="tns:HelloWorldServiceServiceSoapBinding" name="HelloWorldServicePort"> <soap:address location="http://localhost:8081/hello"/> </wsdl:port> </wsdl:service> </wsdl:definitions> |
Trong Mule 4, tất cả các tập tin resources nên nằm trong thư mục src/main/resources và đối với các tập tin định nghĩa các REST hoặc SOAP API, chúng nên nằm trong thư mục api sẵn có nên mình sẽ không bỏ tập tin hello.wsdl nằm trong thư mục src/main/wsdl như trong Mule 3 nữa:
Bây giờ chúng ta sẽ generate các Mule Flows từ tập tin .wsdl này các bạn nhé!
Tương tự như trong Mule 3, các bạn cũng right-click vào tập tin hello.wsdl sau đó chọn Mule rồi chọn “Generate Flows from WSDL”, cửa sổ sau cũng sẽ xuất hiện:
Các bạn cũng để mặc định rồi nhấn nút OK như trong Mule 3 nhé!
Khi đó, các bạn cũng sẽ thấy Mule Flows được generate như sau:
Như các bạn thấy, tương tự như trong Mule 3, Anypoint Studio 7 cũng đã generate các Mule Flows sử dụng APIkit SOAP với một api-main Mule Flow sẽ tiếp nhận request từ client và mỗi operation của SOAP Web Service sẽ được generate thành một Mule Flow. Nhiệm vụ của chúng ta cũng chỉ là implement Mule Flow cho từng operation là xong.
Mặc định thì Mule Flow cho mỗi operation chỉ có một endpoint Transform Message. Nội dung của endpoint Transform Message này sẽ tuỳ thuộc vào operation của SOAP Web Service sẽ có nội dung khác nhau. Trong ví dụ này của mình, nội dung của endpoint Transform Message cho operation hello như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
%dw 2.0 output application/java ns soap http://schemas.xmlsoap.org/soap/envelope --- { body: { soap#Fault: { faultcode: "soap:Server", faultstring: "Operation [hello:\soapkit-config] not implemented" } } write "application/xml" } |
Các bạn có thể remove endpoint Transform Message này để implement Mule Flow này theo cách của mình nhưng phải tuân thủ định nghĩa của tập tin WSDL nha các bạn.
Mình sẽ edit endpoint Transform Message của operation hello để build SOAP response message return về cho client với nội dung như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
%dw 2.0 output application/java ns soap http://schemas.xmlsoap.org/soap/envelope ns ns0 http://muleesbcxfsoapexpose.huongdanjava.com/ --- { body: { ns0#helloResponse: { result: "Hello, " ++ payload.body.ns0#hello.name } } write "application/xml", headers: { clientId: { ns0#clientId: payload.headers.clientId.ns0#clientId } write "application/xml" } } |
Như các bạn thấy, khác với Mule 3, phần <Body> và phần <Header> của SOAP response message trong Mule 4 sẽ được convert từ nội dung của Payload chứ không còn tách biệt nữa. Và khi client request tới, nội dung của SOAP message cũng được gói gọn trong Payload của Mule Message các bạn nhé!
Mặc định thì khi generate Mule Flows từ .wsdl file, phần HTTP Listener Connector sẽ có cấu hình mặc định như sau:
Global Element Properties:
Để đúng với định nghĩa của tập tin hello.wsdl, mình sẽ sửa lại giá trị của phần Path thành “/hello” như sau:
Đến đây là chúng ta đã hoàn thành một ví dụ đơn giản để expose SOAP Web Service sử dụng APIkit SOAP trong Mule 4 rồi đó các bạn!
Kết quả của ví dụ mình sẽ như sau: