SOAP 방식의 웹서비스 – axis2 엔진에서 multi part 입력하기

[ERROR] More than one part for message


SOAP 웹 서비스 명세를 하다보면,  여러개의 input을 넣고 싶은데 여러개의 part는 입력이 되질 않는다.

“이게 무슨 멍청이같은 인터페이스란 말인가?” 역시나 항상 느끼는 것이지만 SOA를 위한 기술들은 개발자들에게 위화감을 제대로 선물한다.
(혹자들은 SOAP이 SOA를 구성하는 가장 편한 기술로서 채택된 것은 그저 우연에 불과하다 라고 하는데 내 눈엔 둘 다 제대로 된 발전을 하지 않고 말만 많은 인간들 사이에서 나와서 똑같이 바보스럽다… 알만한 개발자들은 다 안다.)

SOAP 웹서비스에서 여러개의 Input Parameter를 넘기는 방법은 아래와 같이 두개가 있다.

1. Part를 하나 사용하는 경우 : 기본 SOAP에서 사용하는 데이터 타입인 Element는 내부에 다시 Primitive 타입들을 선언할 수 있다. 그 자체로서 복합 구조이므로 사실상 Part하나를 Element하나로 지정하여 사용해도 해당 서비스에게 여러개의 Input을 전달 할 수 있다.

2. Part를 여러개 사용하는 경우 : Part를 여러개 선언하고 type을 지정해 주는 방법이다.

1번 방법을 사용할 수 있지만, 대부분의 Eclipse를 사용한 개발자는 BPEL Designer GUI를 사용하게 될거고, WSDL이 이쁘게 보이는데 본능적으로 Part를 여러개 두어서 보기 좋게 하고 싶을것이다.

2번 방법을 하고자 할때 [ERROR] More than one part for message 같은 황당한 Error를 맞는 이유는 Multi-part는 RPC-style에서만 사용가능하기 때문이다. Document-style은 1번 방법만을 지원한다.

취향의 문제겠지만, 일반적으로 Depth가 생기면 개발자든 사용자든 간에 사람은 짜증이 난다.
그리고 대부분의 간단한 테스트용 클라이언트는 part를 사용해서 개별적으로 input을 받는다. 다음의 방법으로 RPC 스타일로 선언하여 multi-part를 사용할 수 있다.

기본 구성으로 WSDL을 생성하면 다음과 같이 element가 선언된다. (PrintOut은 임의로 지정한 값)

<element name=”PrintOutRequest”>
<complexType>
<sequence>
<element name=”input” type=”string”/>
</sequence>
</complexType>
</element>
<element name=”PrintOutResponse”>
<complexType>
<sequence>
<element name=”result” type=”string”/>
</sequence>
</complexType>
</element>
그리고 다음과 같이 Request/Response Message 타입이 선언된다.
<message name=”PrintOutRequestMessage”>
<part name=”payload” element=”tns:PrintOutRequest”/>
</message>
<message name=”PrintOutResponseMessage”>
<part name=”payload” element=”tns:PrintOutResponse”/>
</message>
Part를 하나 사용하고 element 를 정의 해서 사용하지 않고 multi-part를 사용하고자 한다면, 아래와 같이 수정한다.
<message name=”PrintOutRequestMessage”>
<part name=”payload” type=”p:string” />
<part name=”payload2″ type=”p:string”/>
</message>
<message name=”PrintOutResponseMessage”>
<part name=”payload” type=”p:string”/>
</message>
그리고 (보통 WSDL의 아래쪽에 위치하는) Binding Definition에서 style을 RPC로 변경해 준다.
<binding name=”PrintOutBinding” type=”tns:PrintOut”>
<soap:binding style=”rpc”    
transport=”http://schemas.xmlsoap.org/soap/http” />
<operation name=”process”>
<soap:operation
soapAction=”http://print.bpel.tps/process” style=”rpc” />
<input>
<soap:body namespace=”http://print.bpel.tps” use=”literal”/>    
</input>
<output>
<soap:body namespace=”http://print.bpel.tps” use=”literal” />
</output>
</operation>
</binding>
이렇게 해주면 multi-part를 이용해서 복수개의 인자 를 받을수 있다.