1. WSDL 소개
WSDL(Web Service Description Language)은 IBM, MS, 아리바에 의해 정의됐으며, 현재 WSDL 1.1 버전으로 W3C에 표준을 위해 제출된 상태이다. WSDL 스펙에서는 WSDL을 다음과 같이 정의한다.
WSDL은 네트워크에 존재하는 원격 서비스를 절차 중심 혹은 문서 중심의 정보를 포함하는
메시지에서 작동하는 종점(endpoint)으로 기술하기 위한 XML 형식이다.
이와 같은 정의를 통해서 WSDL은 네트워크에서 메시지를 주고받는데 사용할 수 있는 서비스를 기술하기 위한 XML 형식의 언어라는 것을 알 수 있다.
웹 서비스에서 WSDL이라는 웹 서비스 기술 언어를 이용하면 웹 서비스를 이용하는 클라이언트 프로그램 개발자에게는 어떠한 이점이 있을까?
1. 웹 서버에 위치하는 WSDL은 누구나 참조할 수 있고, 이를 통해 쉽게 웹 서비스 사용에 필요한 정보를 얻을 수 있다.
2. WSDL을 통해 웹 서비스 작성 및 유지관리가 쉬워진다.
3. 웹 서비스를 이용하기 위해 작성해야 하는 클라이언트 코드 양이 줄어든다.
4. 웹 서비스를 이용하기 위한 정보를 클라이언트 응용 프로그램이 작동하는 동안 동적으로 받을 수 있다. 웹 서비스의 클라이언트에 대한 동적 바인딩 기능이 서비스의 변화가 클라이언트에 큰 영향을 주지 않는다.
5. WSDL은 웹 서비스의 위치 정보를 포함하는데, 웹 서비스를 위한 공용 저장소가 있을 경우, 클라이언트는 쉽게 실제 웹 서비스의 위치에 상관없이, 자신이 원하는 서비스를 찾아서 이용할 수 있다.
① 웹 서비스 제공자는 웹 서비스의 기능, 즉 프로시저의 이름, 인자의 종류, 반환형의 종류, 전송 프로토콜의 종류 그리고 웹 서비스 종점 URL 등을 WSDL 문서로 작성해서 웹 서비스 소비자가 언제든지 다운로드 받을 수 있도록 웹 서버에 저장한다.
② WSDL 문서의 다운로드 URL을 UDDI 레지스트리에 공개한다.
③ 웹 서비스 소비자인 클라이언트 응용 프로그램은 UDDI 레지스트리에서 웹 서비스 명세서인 WSDL 문서를 다운로드 받을 수 있는 URL을 얻는다.
④~⑤ 실제로 해당 URL에서 WSDL 문서를 요청하고 다운로드 받는다.
⑥ 클라이언트 응용 프로그램은 WSDL 문서를 해석하여 웹 서비스 시스템의 사용법을 파악한다.
⑦~⑧ SOAP 메시지를 생성하여 전송하고 결과를 돌려받는다.
2. WSDL 구조
WSDL을 살펴보면, 웹 서비스 정보가 추상적 정의(abstract definition)와 실제 구현(concrete binding)으로 분리되어 기술된 것을 확인할 수 있다. 처음에 WSDL을 본 사람이라면 누구나 왜 이렇게 복잡한 구조를 사용하는 지 의문이 생길 것이다. WSDL의 이러한 구조는 WSDL에서 정의한 요소들의 재사용을 목적으로 한다. 즉, 한 WSDL에서 이미 정의된 요소를 다른 WSDL에서 사용할 수 있다는 것이다. 웹 서비스를 기술하기 위해서 다음과 같은 요소들을 사용한다.
* types : WSDL 안에서 쓰이는 데이터 타입
* message : 서비스 호출을 위한 메소드 인자
* operation : 서비스 호출을 위한 메소드 용법
* portType : operation의 집합
* binding : 메소드 호출을 위한 전송 프로토콜
* port : 웹 서비스 위치
* service : port의 집합
위의 요소 중 message, operation, portType은 메소드 호출을 위한 추상적인 정의를 가지는 요소이며, 이러한 추상적인 정보를 가지는 요소는 binding 요소를 통해 SOAP과 같은 실제 프로토콜과 매핑된다.
마지막으로, 이렇게 매핑된 정보는 port와 service 요소를 통해 실제 웹 서비스 위치와 연결된다. 이렇게 구현된 WSDL에서 추상적인 정의를 가지는 요소와 실제 구현을 담고 있는 요소들은 다른 WSDL의 요소와도 서로 매핑될 수 있다. 즉 새로운 WSDL을 만들 경우, 매번 데이터 타입이나 메소드 정보를 선언하는 것이 아니라, 이미 존재하는 다른 WSDL로부터 필요한 정보를 가져와 재사용할 수 있다는 의미이다.
다음 그림은 WSDL이 가지는 요소가 WSDL 문서 안에서 어떻게 나타나는 지를 보여준다.
지난 시간에 배운 Hello 서비스(sayHello() 메소드 제공)의 WSDL 문서의 예제를 통해서 WSDL 전체 구성을 이해하기 바란다.
Hello 서비스의 webservice.wsdl <?xml version="1.0" encoding="UTF-8"?> targetNamespace="http://localhost:8080/hello/webservice/wsdl/webservice"
<message name="HelloIF_sayHello">xmlns:tns="http://localhost:8080/hello/webservice/wsdl/webservice" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"> <types/>
<part name="String_1" type="xsd:string"/> </message> <message name="HelloIF_sayHelloResponse"> <part name="result" type="xsd:string"/> </message> <operation name="sayHello" parameterOrder="String_1">
<input message="tns:HelloIF_sayHello"/><output message="tns:HelloIF_sayHelloResponse"/> </operation> </portType> <binding name="HelloIFBinding" type="tns:HelloIF"> <operation name="sayHello"> <input> <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="encoded" namespace="http://localhost:8080/hello/webservice/wsdl/webservice"/> </input> <output> <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="encoded" namespace="http://localhost:8080/hello/webservice/wsdl/webservice"/> </output> <soap:operation soapAction=""/> </operation> </binding> <service name="Webservice"> <port name="HelloIFPort" binding="tns:HelloIFBinding"> <soap:address location="REPLACE_WITH_ACTUAL_URL"/> </port> </service> </definitions> |
다음은 WSDL 문서의 구조를 이루는 주요 엘리먼트에 대한 설명이다.
엘리먼트 | 용도 | 작성회수 |
<definitions> | WSDL 문서의 루트 엘리먼트로서, WSDL 안에서 쓰이는 엘리먼트들을 위해 여러 네임스페이스가 선언된다. | 1회 |
<types> | WSDL에서 쓰이는 데이터타입, 즉 인자와 반환형에서 사용될 복합 타입을 기술한다. | 0 또는 1회 |
<message> | 원격 프로시저 호출에서 사용될 인자와 반환값에 대한 정보를 기술한다. | 1회 이상 |
<operation> | 원격 프로시저에 대한 정보를 기술한다. | 1회 이상 |
<binding> | 호출에 사용되는 프로토콜에 대한 정보를 기술한다. | 1회 이상 |
<service> | 웹 서비스 시스템의 종점 URL을 기술한다. | 1회 이상 |
엘리먼트 | 용도 | 작성회수 |
<documentation> | 사람이 읽기 위한 주석을 기술한다. | 0회 이상 |
<import> | 루트 엘리먼트의 첫 번째 자식요소로 사용되어, 외부 XML 문서에 정의되어 있는 내용을 참조할 때 사용된다. | 0회 이상 |
3. 서비스의 정의
3.1 <definitions>
WSDL의 각 요소들이 다른 WSDL의 요소를 참조하거나 또는 참조되기 때문에, 참조되는 각 요소들은 반드시 특정한 네임스페이스로 구별되어야한다. 여러분이 앞으로 자주 보게 될 WSDL의 요소들은 이미 특정한 네임스페이스와 연관되어 있다. 다음의 표는 WSDL에서 관례적으로 쓰이는 네임스페이스와 이를 사용하기 위한 권장 접두사를 나타낸다.
접두사 | 네임스페이스명 | 설명 |
wsdl | http://schemas.xmlsoap.org/wsdl/ | WSDL에 대한 네임스페이스 |
soap | http://schemas.xmlsoap.org/wsdl/soap/ | SOAP 바인딩에 대한 네임스페이스 |
http | http://schemas.xmlsoap.org/wsdl/http/ | HTTP GET & POST 바인딩에 대한 네임스페이스 |
mime | http://schemas.xmlsoap.org/wsdl/mime/ | MIME 바인딩에 대한 네임스페이스 |
soapenc | http://schemas.xmlsoap.org/soap/encoding/ | SOAP 1.1에서 정의한 인코딩 네임스페이스 |
soapenv | http://schemas.xmlsoap.org/soap/envelope/ | SOAP 1.1에서 정의한 엔벨로프 네임스페이스 |
xsi | http://www.w3.org/2001/XMLSchema-instance | XML Schema 인스턴스에 대한 네임스페이스 |
xsd | http://www.w3.org/2001/XMLSchema | XML Schema 언어에 대한 네임스페이스 |
tns | 사용자 정의 | 현재 WSDL 문서에서 정의한 요소를 위한 네임스페이스 |
<definitions> 엘리먼트는 다음과 같은 용도의 2개의 속성을 가질 수 있다.
속성명 | 용도 |
name | WSDL 문서의 내부 이름을 기술 |
targetNamespace | WSDL에서 정의하는 원격 프로시저에 대한 네임스페이스 이름 기술 |
다음은 WSDL의 <definitions> 엘리먼트의 전형적인 사용 예를 보여준다.
<definitions name="webservice" targetNamespace="http://localhost:8080/hello/webservice/wsdl" xmlns:tns="http://localhost:8080/hello/webservice/wsdl" xmlns:ns2="http://localhost:8080/hello/webservice/type" xmlns="http://schemas.xmlsoap.org/wsdl" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap" xmlns:xsd="http://www.w3.org/2001/XMLSchema" ~ </definitions> |
임의의 웹 서비스를 제공하거나 사용할 경우, 그 웹 서비스에서 사용되는 데이터 타입을 정의해야 한다.
예를 들면, 책 판매 웹 서비스를 이용하기 위해 사용자는 책 이름과 수량에 관한 메시지를 전달할 것이고, 그 메시지를 받은 서비스는 책 판매가격을 반환할 것이다. 여기서 웹 서비스를 이용하기 위해 사용자는 책 이름은 문자열 타입이고 수량과 반환값인 책 판매가격은 정수형이 된다.
이렇게 웹 서비스에서 사용되는 데이터 타입을 WSDL에서는 <types>라는 엘리먼트를 통해 정의할 수 있다. 이러한 데이터 타입 정의를 위해 WSDL은 XML 스키마를 이용할 수 있다. 물론 웹 서비스 공급자와 사용자 사이에 정해진 데이터 타입이 있다면 그것을 사용해도 상관없다. WSDL에서 데이터 타입을 정의할 때 XML 스키마의 사용을 강요하지는 않는다. 그러나 이기종의 여러 플랫폼과 다른 언어로 구현된 응용 프로그램이 데이터를 교환하려면 표준화된 중립 데이터 형식을 이용하는 것이 가장 좋은 선택이라고 할 수 있으며, 이를 위해 WSDL 스펙의 저자들이 XML을 선택한 것이다. 따라서 XML 스키마로 웹 서비스에서 사용되는 메시지의 데이터 타입을 쉽게 정의할 수 있고, 이렇게 정의된 데이터 타입은 XML 스키마라고 하는 표준 데이터 정의 방식을 따른 것이기 때문에 모든 사람들이 쉽게 공유 할 수 있다.
<types> 엘리먼트는 원격 프로시저의 인자 및 리턴값의 데이터 타입으로 사용될 복합 타입을 기술하기 위한 엘리먼트로서, 만약 인자 및 반환값의 자료형으로 복합 데이터 타입이 사용되지 않는다면 생략 가능한 요소이다.
WSDL 문서의 <message> 엘리먼트에 기술되는 인자 및 리턴값의 데이터 타입이 XML 스키마의 빌트인 단순 타입으로 표현될 수 있다면 XML 스키마 타입을 직접 사용한다.
하지만 배열 및 구조체와 같이 XML 스키마에 없는 자료형이 사용되는 경우에는 반드시 <types> 엘리먼트에 배열 및 구조체에 해당하는 복합 타입을 정의해야만, 이것을 통해서 웹 서비스 클라이언트가 스텁을 생성할 수 있다.
다음은 <types> 엘리먼트의 작성 문법이다.
<types> <schema targetNamespace ="복합 타입 네임스페이스명"
xmlns:tns="복합 타입 네임스페이스명" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl"
xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.w3.org/2001/XMLSchema"> <complexType name="복합타입명"> ~~ </complexType> </schema> </types> |
targetNamespace="http://localhost:8080/hello/webservice/type"는 복합 데이터 타입에 대한 네임스페이스 이름을 지정한 것이다.
xmlns:tns="http://localhost:8080/wsdl/webservice"은 타켓 네임스페이스에 대한 네임스페이스 선언으로서 필수 사항은 아니다. 하지만 <schema> 엘리먼트 내에서 정의된 복합 타입이 <schema> 엘리먼트 내의 다른 엘리먼트에서 참조될 경우 QName 형태로 기술되기 때문에 이러한 경우에는 반드시 필요한 부분이다.
|
데이터 타입으로 “복합타입명”을 선언하고, 데이터 타입은 XML 스키마의 Complex Type이다. 이 데이터 타입은 뒤에 소개할 <message> 엘리먼트에서 웹 서비스를 사용하기 위한 메시지를 정의하는데 사용된다. |
① 배열을 정의하는 경우
원격 프로시저 sayHello1()이 다음과 같은 String 배열을 가지는 경우라면 String sayHello1( String msg[] ) { ~ ~ }
위와 같이 인자가 배열인 경우에는 다음과 같이 복합 타입을 작성한다.
<complexType name="배열타입이름"
<complexContent> <restriction base="soap-enc:Array"> <attribute ref="soap-enc:arrayType" wsdl:arrayType="데이터타입[]"/> </restriction> </complexContent> </complexType> |
② 구조체를 정의하는 경우
원격 프로시저 sayHello2()가 다음과 같은 클래스 타입을 인자로 가지는 경우라면 String sayHello2( 클래스명 msg) { ~ ~ }
자바에서는 구조체가 없기 때문에 대신 class형을 정의하는 문법을 생각하면 된다. <complexType name="클래스명">
<sequence> <element name="멤버변수명1" type="데이터타입1"/> <element name="멤버변수명2" type="데이터타입2"/> ~ ~ </sequence> </complexType> |
3.3 <message>
<message> 엘리먼트는 웹 서비스에서 사용되는 메시지에 대한 추상적인 정의를 담는 요소이다. 여기서 추상적인 정의란 의미는 <message> 요소는 단지 웹 서비스에서 쓰일 수 있는 메시지에 대한 정의를 담을 뿐, 실제 이 메시지가 어떠한 형태가 될 지는 정의하지 않는다는 것을 의미한다. 실제 구현에 관해서는 <binding>이라는 엘리먼트를 통해서 정의한다.
<message>는 원격 프로시저의 인자에 대한 정보(인자의 개수 및 인자의 데이터 타입)와 반환값에 대한 정보(반환값의 데이터 타입)를 기술하기 위한 요소로서, 한 개의 원격 프로시저의 인자에 대한 정보는 한 개의 <message> 엘리먼트로 작성되고, 마찬가지로 반환값에 대한 정보도 한 개의 <message>로 작성된다. 그리고 웹 서비스에서 교환되는 데이터(인자 및 반환값 정보)에 대한 구체적인 정보를 정의하기 위해서 하나 이상의 <part>라는 자식 요소를 사용한다. <part>는 <types>에서 언급된 데이터 타입을 참조하며, 직접 XML 스키마의 데이터 타입을 참조할 수 있다.
<message> 요소의 작성 문법은 다음과 같다.
<message name="메시지 이름"> <part name="인자 또는 반환 변수 이름" type="데이터 타입"/>
</message>
|
<message> 요소의 name 속성은 <message>의 이름을 기술하기 위한 것으로, 이것의 속성값은 <operation> 요소를 작성할 때 참조되기 때문에 반드시 기술해야하는 필수 속성이다. |
<part> 엘리먼트의 name 속성은 인자 또는 반환값에 해당하는 변수의 이름을 나타내고, type 속성은 이것들에 대한 데이터 타입을 QName 형태로 기술한다. type 속성의 값으로는 단순 타입과 복합 타입을 기술할 수 있는데, 단순 타입의 경우에는 XML 스키마에 정의되어 있는 빌트인 단순 타입을 사용해서 기술하면 된다. 하지만 만약에 인자 또는 반환값의 데이터 타입으로 배열이나 구조체가 사용되는 경우라면 <types> 엘리먼트에서 정의된 복합타입명을 기술해 주면된다. |
Hello 웹 서비스의 원격 프로시저 sayHello()에 대한 <message>는 다음과 같이 작성될 수 있다.
▶ 인자 정보에 대한 <message> 엘리먼트 <message name="HelloIF_sayHello">
<part name="String_1" type="xsd:string"/>
</message>
▶ 실행 결과값의 정보에 대한 <message> 엘리먼트 <message name="HelloIF_sayHelloResponse"> <part name="result" type="xsd:string"/> </message> |
3.4 <portType>과 <operation>
<portType>과 <operation>은 웹 서비스의 인터페이스를 정의하는 부분으로, <portType>은 하나 이상의 <operation>을 포함한다. 웹 서비스 인터페이스를 정의한다는 의미는 <message>에서 정의한 메시지를 이용하여 어떻게 웹 서비스의 메소드를 호출할 지에 대해 기술한다는 것을 의미한다. 이를 위해 해당 메소드의 이름 및 그 메소드를 호출하기 위해 필요한 메시지 그리고 반환값을 정의한다.
웹 서비스를 이용하기 위한 일련의 과정을 WSDL은 operation이라고 하는데, WSDL 스펙에서는 operation을 다음과 같이 4가지 형태로 나누고 있다.
* One-way
웹 서비스 사용자가 요청 메시지를 보낸 후 응답을 받지 않는 경우로, 비동기식 통신을 의미한다.
* Request-Response
웹 서비스 사용자가 요청 메시지를 보낸 후 응답 메시지를 받는 형태로서, 4가지의 operation 중 가장 광범위하게 사용된다. 이유는 웹 서비스의 중요한 사용 목적인 RPC는 원격 메소드 호출 메시지와 응답 메시지가 필요하기 때문이다.
* Solicit-Response
CORBA나 RMI의 콜백과 같이 웹 서비스가 사용자에게 요청하고 응답 메시지를 받는 형태로 아주드문 형태의 operation이다.
* Notification
이벤트 호출과 같이 웹 서비스가 일방적으로 사용자에게 메시지를 보내는 경우이다.
<portType>과 <operation> 엘리먼트를 작성하는 문법은 다음과 같다.
<portType name="포트타입이름"> <operation name="원격프로시저명" parameterOrder="인자_이름 인자_이름 ... "> <input message="인자 타입을 기술한 message 엘리먼트 참조" /> <output message="리턴 타입을 기술한 message 엘리먼트 참조" /> </operation> <operation> ~ </operation> </portType> |
다음 예제는 Request-Response operation에 해당하는 <portType> 및 <operation> 예제이다.
<message name="HelloIF_sayHello"> <part name="String_1" type="xsd:string"/> </message> <message name="HelloIF_sayHelloResponse"> <part name="result" type="xsd:string"/> </message> <portType name="HelloIF"> <operation name="sayHello" parameterOrder="String_1"> <input message="tns:HelloIF_sayHello"/>
<output message="tns:HelloIF_sayHelloResponse"/> </operation> </portType> |
예제에서 HelloIF라는 <portType>은 sayHello라는 이름의 operation을 포함한다. sayHello operation은 입력 메시지로 tns:HelloIF_sayHello, 출력 메시지로 tns:HelloIF_sayHelloResponse를 사용한다. 위 예제의 <operation>을 자바 메소드 형태로 표현하면 다음과 같다.
public String sayHello (String s);
입력 메시지 HelloIF_sayHello와 출력 메시지 HelloIF_sayHelloResponse가 각각 sayHello라는 메소드의 인자와 반환값으로 매핑된 것을 확인할 수 있다.
3.5 <import>
WSDL의 모든 요소가 하나의 파일에 있을 필요는 없다. WSDL의 각 요소는 다른 WSDL 파일에서 참조될 수 있는 데, 한 WSDL의 요소가 여러 파일에 존재하는 경우도 생각할 수 있다. 한 WSDL 파일은 외부의 요소를 사용하기 위해 <import>라는 엘리먼트를 사용한다.
다음 WSDL 파일은 <binding>과 <service> 엘리먼트만 가지고 있는 경우로서, <import> 엘리먼트를 사용한 예제이다.
<?xml version="1.0" encoding="UTF-8"?> <definitions name="webservice" targetNamespace="http://localhost:8080/hello/webservice/wsdl/webservice" xmlns:tns="http://localhost:8080/hello/webservice/wsdl/webservice" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"> <import namespace="http://localhost:8080/hello/webservice/wsdl/import" location="http://localhost:8080/hello/webservice/wsdl/hello-import.wsdl" /> <binding name="HelloIFBinding" type="tns:HelloIF"> <operation name="sayHello"> ~ </operation> </binding> <service name="Webservice"> <port name="HelloIFPort" binding="tns:HelloIFBinding"> ~
</port> </service> </definitions> |
위의 WSDL 파일에서 <binding>과 <service>를 제외한 나머지 요소는 "http://localhost:8080/hello/webservice/wsdl/hello-import.wsdl"에서 발견할 수 있다.
따라서 임포트되는 hello-import.wsdl은 다음과 같은 내용을 가지게 될 것이다.
<?xml version="1.0" encoding="UTF-8"?> <definitions name="webservice" targetNamespace="http://localhost:8080/hello/webservice/wsdl/webservice" ~~~~ "> <types> ~ </types> <message name="HelloIF_sayHello"> ~ </message> <message name="HelloIF_sayHelloResponse"> ~ </message> <portType name="HelloIF">~</portType>
</definitions>
|
hello-import.wsdl 파일에서 <types>, <message>, <portType>의 엘리먼트가 정의된 것을 볼 수 있다.
물론 hello-import.wsdl 파일 역시 외부의 다른 WSDL 파일이나 XML 스키마 파일에서 WSDL 요소 및 데이터를 참조할 수 있다. 이와 같이 WSDL 파일은 <import> 요소를 사용하여 이미 정의되어 있는 WSDL 요소들을 재사용할 수 있다.
4. 바인딩
4.1 바인딩의 개념
지금까지 살펴본 요소, <message>, <types>, <portType>, <operation> 엘리먼트는 웹 서비스의 인터페이스를 정의하는 것이었다. 즉 웹 서비스 시스템이 제공하는 원격 프로시저를 웹 서비스 클라이언트가 어떻게 사용하는 가에 대해서 알려주는 역할을 한다. 그럼 지금부터는 웹 서비스의 인터페이스를 실제 프로토콜과 매핑시키는 <binding> 요소를 살펴보도록 하자.
WSDL에서는 <binding> 엘리먼트를 이용하여 <portType>에서 정의한 operation과 메시지를 실제 전송 프로토콜에 매핑시킨다. 웹 서비스 인터페이스의 정의와 실제 프로토콜과 매핑시키는 과정을 WSDL 스펙에서는 바인딩이라고 한다. WSDL에서 <binding> 엘리먼트 안에서 정의할 수 있는 프로토콜에는 제한이 없지만, WSDL 스펙에서는 이 중 가장 널리 쓰이는 세 가지 프로토콜을 언급하고 있다.
① SOAP 바인딩
웹 서비스 시스템의 원격 프로시저를 호출할 때 SOAP을 통해서 호출 요청하는 방식을 말한다.
③ MIME(Multipurpose Internet Mail Extensions) 바인딩
MIME는 SOAP과 HTTP에서 함께 사용하여 문자 데이터와 이진 데이터(이미지, 동영상)를 함께 전송할 때 사용할 수 있는 방식이다.
원격 프로시저 호출 서비스를 제공하는 대부분의 웹 서비스 시스템에서 사용하는 바인딩 프로토콜은 SOAP이다. 이것은 SOAP이 원격 프로시저 호출용으로 특별히 제작되었기 때문이다.
하지만 웹 서비스 소비자가 다양한 형태의 기기를 사용하고, 실행되는 응용 프로그램이 모두 다르기 때문에 SOAP 바인딩에 추가적으로 HTTP 바인딩을 WSDL 문서에 정의하는 것이 좋을 것이다. 왜냐하면 대부분의 클라이언트가 HTTP를 지원하기 때문이다.
4.2 바인딩의 종류
⑴ SOAP 바인딩
WSDL 문서에서 SOAP 바인딩을 정의하는 문법은 다음과 같다.
<binding name="바인딩명" type="포트타입명"> <soap:binding style="rpc | document" transport="http://schemas.xmlsoap.org/soap/http" /> <operation name="원격프로시저명"> <soap:operation soapAction="HTTP SOAPACTION 헤더값"/> <input> <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="encoded" namespace="원격 프로시저명에 대한 네임스페이스명"/> </input> <output> <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="encoded" namespace="원격 프로시저 호출 결과에 대한 네임스페이스명"/> </output> <fault> <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="encoded" namespace="오류 결과에 대한 네임스페이스명"/> </fault> </operation> </binding> |
<soap:binding> SOAP 메시지 타입과 전송 프로토콜을 정의한다. SOAP 메시지 타입으로는 rpc와 도큐먼트 타입이 있는데, style이라는 속성을 통해 정해진다. SOAP 메시지 타입이 rpc인 경우, WSDL에서 정의한 메소드 이름 및 메시지는 RPC를 위한 SOAP 메시지 형태로 변환된다. style 속성값이 ‘document’인 경우 SOAP 메시지가 문서 타입임을 나타내는데, SOAP 메시지는 WSDL에서 정의된 메시지를 XML 형태 그대로 SOAP 바디에 담는다. 만약 style 속성이 기술되지 않으면 디폴트로 document값을 가진다. 또 하나의 속성으로 transport는 SOAP과 매핑시킬 전송 프로토콜을 정하는 데 사용된다. 위의 <binding>의 경우, 전송 프로토콜로 HTTP가 사용되는 것을 알 수 있다. |
<soap:operation> style과 soapAction 두 가지 속성을 가질 수 있다. style은 <soap:binding>과 동일하면, 이 속성이 없는 경우에는 <soap:binding>의 style 속성값을 그대로 물려받는다. soapAction은 SOAP 메시지 프로토콜로 HTTP가 사용될 때, HTTP 헤더 값인 SOAPAction 헤더의 값을 정하기 위해서 사용된다. 만일 HTTP 이외의 다른 프로토콜과 사용될 때는 이 속성을 사용할 수 없다. soapAction 속성값으로 “” 과 같이 빈 문자열이 지정되는 경우도 있다. 이것은 웹 서비스 클라이언트가 HTTP의 SOAPAction 헤더를 생략해도 좋다는 의미가 아니라 헤더는 언급하되 헤더값을 비워두라는 의미이다. |
<soapbody> 이 요소는 <input>, <output>, <fault> 요소의 자식 요소로 작성되며, WSDL에서 정의한 메시지 정의가 어떻게 인코딩되어 SOAP 바디에 나타날 지를 정의한다. 특정한 인코딩 방식을 사용하기 위해 use라는 속성과 encodingStyle 속성을 사용한다. use 속성값으로는 literal과 encoded값을 가질 수 있는데, literal은 인코딩 적용 없이 SOAP 메시지 자체를 그대로 전달하는 뜻이다. encoded는 반드시 encodingStyle 속성에 언급되어 있는 방식을 사용해서 표기하라는 의미이다. 일반적으로 원격 프로시저 호출은 use 속성값으로 encoded를 기술하고, encodingStyle 속성값으로 “http://schemas.xmlsoap.org/soap/encoding/”을 기술한다. |
다음은 Hello 웹 서비스에 대해서 SOAP 바인딩을 정의한 WSDL 문서 내용이다.
~ <binding name="HelloIFBinding" type="tns:HelloIF"> <operation name="sayHello"> <input> <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="encoded" namespace="http://localhost:8080/hello/webservice/wsdl/webservice"/> </input> <output> <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="encoded" namespace="http://localhost:8080/hello/webservice/wsdl/webservice"/> </output> <soap:operation soapAction=""/> </operation> </binding> ~ |
⑵ HTTP 바인딩
HTTP 바인딩은 WSDL에서 언급하고 있는 SOAP 이외의 또 다른 바인딩 타입이다. 어떤 웹 서비스를 HTTP 바인딩을 통해 접근할 수 있다면, 이 웹 서비스는 웹 브라우저를 통해 사용할 수 있다. 이것의 의미는 HTTP를 이용할 수 있는 모든 응용 프로그램에서 이 웹 서비스를 사용할 수 있다는 말이다.
HTTP 바인딩에는 다음과 같은 세 가지 종류가 있다.
* URL 인코딩을 통한 HTTP GET
* URL 변환을 통한 HTTP GET
* HTTP POST
① URL 인코딩을 통한 HTTP GET
SOAP 바인딩과 마찬가지로 모든 형태의 HTTP 바인딩은 http라는 접두사를 가진다. 다음 예제를 살펴 보자.
<binding name="HelloIFBinding" type="tns:HelloIF"> <http:binding verb="GET"/> <operation name="sayHello"> <http:operation location="sayHello"/> <input> <http:urlEncoded/> </input> <output> <mime:content type="text/html"/> </output> </operation> </binding> |
<http:binding> 이 요소에서 verb라는 속성은 GET 또는 POST가 될 수 있는데, 여기에서는 GET 방식으로 메시지가 전달되었다. |
<http:operation> 이 요소의 location 속성에는 원격 프로시저명을 기술해 준다. 원격 프로시저명은 웹 서비스 시스템의 종점 URL 뒤에 붙여질 상대 경로명에 해당된다. |
<mime:content type="text/html"/>은 원격 프로시저 실행 결과가 HTML 문서 형태로 클라이언트에 전달된다는 뜻이다. |
② URL 변환을 통한 HTTP GET
<http:urlEncoded> 이것은 <input> 요소의 자식 요소로 웹 서비스 요청이 표준 HTTP 인코딩을 따른다는 것을 말한다. 만일 입력 <message>가 string 타입의 msg이라는 이름의 <part>를 가지면 웹 서비스 사용을 위해 다음과 같은 HTTP 요청이 사용된다. http://localhost:8080/hello/webservice/sayHello?msg=Hello |
이 방식은 앞서 설명한 URL 인코딩을 통한 HTTP GET 방식과 거의 유사하다. 한 가지 다른 점은 입력 메시지의 처리인데, 입력 메시지가 HTTP 표준 인코딩으로 처리되지 않고, <http:operation>의 location 속성값에 직접 삽입된다는 것이다. 다음의 예제를 살펴보자.
<binding name="HelloIFBinding" type="tns:HelloIF"> <http:binding verb="GET"/> <operation name="sayHello"> <http:operation location="sayHello/(msg)"/> <input> <http:urlEncoded/> </input> <output> <mime:content type="text/html"/> </output> </operation> </binding> |
location 속성에 msg가 첨부된 것을 알 수 있다. 만일 msg 값으로 Hello가 주어지면 웹 서비스에 대한 HTTP 요청은 다음과 같다.
http://localhost:8080/hello/webservice/sayHello/Hello
③ HTTP POST
<http:binding> 요소의 verb 속성에 POST를 기술하는 경우로서, 웹 페이지가 입력 메소드를 form 형태로 전달하면, HTTP POST 형태의 바인딩을 사용할 수 있다.
다음 예제를 보면 form으로 전달된 데이터를 인코딩하기 위해 <mime:content>의 type 속성값으로 “application/x-www-form-urlencoded"가 사용된 것을 알 수 있다.
<binding name="HelloIFBinding" type="tns:HelloIF"> <http:binding verb="POST"/> <operation name="sayHello"> <http:operation location="sayHello)"/> <input> <mime:content type="application/x-www-form-urlencoded"/> </input> <output>
<mime:content type="text/html"/> </output> </operation> </binding> |
⑶ MIME 바인딩
이것은 HTTP 바인딩 및 SOAP 바인딩과 같이 사용되어 MIME 인코딩을 지원하여, 문자 데이터와 이진 데이터를 함께 전송할 때 사용할 수 있는 방식이다. MIME 바인딩을 위해 다음과 같은 MIME 타입을 지원한다.
* multipart/related
다른 MIME 타입의 여러 부분으로 구성된 메시지를 구성할 경우
* text/xml
XML 형태로 인코딩된 메시지를 정의할 경우
* application/x-www-form-urlencoded
HTML Form을 통해 전달되는 데이터 형식으로 인코딩할 경우
* Others
단지 MIME 타입 정의만을 필요로 하는 모든 MIME 타입
MIME 바인딩에 대한 예는 HTTP POST 바인딩 예제를 통해서 확인할 수 있다. 그 예제에서 sayHello라는 operation의 입력 메시지는 웹 페이지의 form을 통해 전달되는 데이터 형식으로 인코딩되는 것을 볼 수 있다.
4.3 <service>와 <port>
웹 서비스 클라이언트는 원격 프로시저 호출을 위한 프로토콜을 이해하였다면, 그러면 이러한 프로토콜을 어디로 보낼 것인지를 알아야한다. 즉 수신자인 웹 서비스 시스템의 종점 URL 정보를 알아야 한다.
웹 서비스 제공자는 웹 서비스 시스템에 대한 URL 정보를 WSDL 문서의 <service> 요소에 기술하고, 그러면 웹 서비스 클라이언트는 WSDL 문서의 <service> 요소의 내용을 보고 웹 서비스 시스템에 바인딩한다.
웹 서비스 시스템은 수많은 클라이언트의 접속을 분산시켜 빠른 서비스를 제공하기 위해서 분산되어 여러 개가 운영될 수 있으며, 어떤 경우에는 바인딩 방식에 따라 분리해서 운영할 수도 있다. 따라서 <service> 요소는 자식 요소인 <port>요소를 여러 개 가질 수 있도록 하여 여러 개의 웹 서비스 시스템에 대한 URL 정보를 기술할 수 있도록 하고 있다.
<service> 요소를 작성하기 위한 문법은 다음과 같다.
<service name="웹 서비스 명"> <port name="포트이름" binding="해당 바인딩 이름 참조"> <soap:address location="웹 서비스 시스템 URL"/> </port> ~~
<port name="포드이름" binding="해당 바인딩 이름 참조"> <http:address location="웹 서비스 시스템 URL"/> </port> ~~ </service> |
정리하기
⑴ WSDL은 네트워크에 존재하는 원격 서비스를 절차 중심 혹은 문서 중심의 정보를 포함하는 메시지에서 작동하는 종점(endpoint)으로 기술하기 위한 XML 형식의 문서이다.
웹 서비스 제공자는 자사가 제공하는 웹 서비스의 기능을 명세화하여, UDDI 레지스트리(저장소)에 공개하고, 웹 서비스 소비자는 웹 서비스 제공자가 공개한 웹 서비스의 명세를 참조하여 웹 서비스의 사용법(원격 프로시저명, 인자, 반환형, 프로토콜의 종류, 웹 서비스 시스템 URL 등)을 알게 된다.
⑵ 실제 웹 서비스 사용자가 호출할 서비스의 인터페이스 정보를 얻는 과정을 정리해 보자.
① WSDL 문서에서 <service> 부분을 참조하여 웹 서비스가 어떤 서비스를 제공하는지 알기 위해 <port> 요소(HelloIFPort)의 바인딩 속성(tns:HelloIFBinding)을 얻는다.
② 이제 WSDL 문서에서 <binding> 부분을 참조하여 해당 바인딩이 가지는 XML 정의의 operation 정보인 type 속성값(tns:HelloIF)을 얻는다.
③ WSDL 문서의 <portType> 요소에 정의된 operation의 XML 정의를 얻는다.
④ <portType> 요소에 사용된 여러 message 유형(tns:HelloIF_sayHello)을 알기 위해 <message> 요소를 참조한다.
⑤ WSDL 문서의 <message> 요소에서 operation 정의에 사용된 타입들의 정보(HelloIF_sayHello)를 확인한다. 이때 사용자 정의 타입(HelloType)이 있다면 <types> 요소를 참조한다.
⑥ WSDL 문서의 <types> 요소를 참조하여 사용자 정의 타입 정보를 얻는다.
이와 같은 과정은 다음과 같은 그림을 표현할 수 있다.
'정보과학 > 웹서비스특론' 카테고리의 다른 글
웹 서비스 보안 (0) | 2023.09.14 |
---|---|
웹 서비스 공개 및 검색, UDDI (0) | 2023.09.13 |
웹 서비스 클라이언트 개발 (1) | 2023.09.11 |
웹 서비스 시스템 개발 (1) | 2023.09.09 |
SOAP API (0) | 2023.09.08 |