본문 바로가기
정보과학/웹서비스특론

SOAP

by J1소프트 2023. 9. 7.
728x90

1. SOAP 개요

 

1.1 SOAP이란 무엇인가?

(1) SOAP 스펙에서의 정의

"SOAP은 분산 환경에서 HTTP를 통해 정보를 교환하기 위한 표준 XML 기반의 가벼운 프로토콜이다"

 

여기서 가벼운(light weight)이란 의미는 기존의 다른 분산 프로토콜 비해 상대적으로 많은 특징이 생략되어 단순히 시스템 간의 데이터 교환을 위한 메시지 형식을 정의하고 있다는 뜻이다.

 

SOAP이란?

SOAPSimple Object Access Protocol의 약자이다.

SOAP은 통신(communication) 프로토콜이다.

SOAP은 응용 프로그램 간의 통신을 위한 것이다.

SOAP은 메시지 전송을 위한 포맷이다.

SOAP은 인터넷을 통해서 통신하도록 설계되었다.

SOAP은 플랫폼 독립적이다.

SOAP은 구현언어에 독립적이다.

SOAP은 간단하고 확장성이 있다.

SOAP은 방화벽을 통과할 수 있다.

SOAPW3C 표준으로 발전할 것이다.

(2) SOAP 설계 목표
SOAP 스펙에서 언급하는 SOAP의 가장 중요한 설계 목표는 단순함(simplicity)과 확장성(extensibility)이다. 이를 위해 SOAP에서는 기존 메시징과 분산 시스템이 가지는 다음과 같은 특징을 포함하지 않는.

          ► 분산 쓰레기 수집(distributed garbage collection)

          다중 메시지 처리(boxcarring or batching of messages)

          객체 참조(objects-by-reference)

          활성화(activation)

 

SOAP이라는 프로토콜은 분산 프로그램을 위한 것이지만 분산 프로그래밍을 위한 어떠한 특별한 내용이나 제한 사항을 담고 있지 않다. 실제로 SOAP 메시지에 포함되는 내용은 호출할 서비스 이름, 메소드 이름, 호출 인자가 전부이다.

 

(3) SOAP 버전

현재 SOAP1.2 버전까지 나와 있는데, 스펙에서 SOAP 1.1과의 커다란 차이는 없다. 그러나 버전1.1이 현재 널리 사용되고 있으며 지원되는 툴 역시 SOAP 1.1을 더 광범위하게 지원하고 있다.

<참고 사이트>

SOAP 스펙
http://www.w3.org/TR/soap/

1.2 SOAP 프로토콜의 장점

SOAP은 경량의 프로토콜이다.

SOAP의 구성요소들이 다른 분산 컴퓨팅 프로토콜의 내용보다 적기 때문에 프로토콜 자체가 복잡하지 않다

 

텍스트 기반의 XML 포맷을 사용한다

기존의 분산 컴퓨팅 프로토콜은 이진 포맷의 메시지를 사용하기 때문에 플랫폼, 소프트웨어 등에 종속적이지만, SOAPXML로 구성되어 하드웨어, 운영체제, 구현 언어 등에 독립적이기 때문에 XML을 이해하는 모든 시스템 간에는 서로 정보를 교환할 수 있다.

 

HTTP로 전송 가능하기 때문에 인터넷에 연결된 어떤 시스템과도 통신이 가능하다

 

HTTP를 사용하기 때문에 방화벽을 쉽게 통과할 수 있다. 이것은 장점이 되는 동시에 심각한 보안 문제를 대두시킬 수 있는 단점이 되기도 한다.

 

1.3 SOAP을 사용하는가?

서로 다른 분산 컴퓨팅 프로토콜(CORBA, DCOM, RMI )을 사용하는 소프트웨어 컴포넌트를 묶어서 하나의 분산 응용 프로그램을 개발하기 위해서 SOAP을 사용할 수 있다. SOAP은 각기 다른 프로토콜을 사용하는 컴포넌트의 중계자 역할을 수행하여 서로 접근할 수 없었던 것을 가능하게 만들어준다. 라서 각기 다른 컴퓨팅 프로토콜을 사용하는 시스템 사이에 SOAP 응용 프로그램만 추가하면, 각 프로토콜의 세부 내용들을 변경하지 않고도 다른 시스템의 객체를 사용할 수 있다.

 

1.4 SOAPXML

SOAP을 공부하기 전에 XMLXML 네임스페이스에 대한 기본적인 사항들을 이해하고 있어야만 하며SOAPXML과의 관계를 간단히 정리하면 다음과 같다.

 

모든 SOAP 메시지는 XML로 표현된다. , SOAPXML 스키마와 네임스페이스 같은 XML 표준 기술을 이용하여 메시지에 쓰이는 데이터와 여러 기능을 기술한다.

 

SOAP 메시지를 작성할 때, SOAP의 모든 기본 요소는 반드시 특정한 네임스페이스에 속하게 함으로써 SOAP의 기본요소와 사용자 정의 요소를 명확히 구분한다.

 

SOAP 메시지를 사용할 때 DTDPI는 포함할 수 없다.


2. SOAP 메시지 구조

2.1 SOAP 메시지의 구성

SOAP 메시지는 그림과 같은 세 부분으로 이루어진 XML 문서로서, 메시지의 구조는 편지를 보낼 때 필요한 구성 요소와 비슷하다. 봉투는 편지 봉투에 해당되며, 편지 봉투에는 송신자의 이름과 기타 정보가 기술되는데 이런 정보가 바로 헤더에 기술된다. 그리고 바디 부분은 편지 내용에 해당된다.

그림 1. SOAP 메시지의 구성요소

<참고 사이트>

SOAP 메시지의 구조를 정의한 XML 스키마 문서

SOAP 메시지의 XML 문서 표현

<?xml version="1.0" encoding="UTF-8"?>
<Envelope>
          <!-- Header 부분 (선택) -->
          <Header>
                    ~ 메시지 라우팅, 인증, 트랜잭션 등 메시지를 처리하는 방법을 포함
          </Header>
          <!-- Body 부분 (필수) -->
          <Body>
                    ~ 실제 전달하는 XML 형식의 메시지 내용을 포함
          </Body>
</Envelope>
네임스페이스 선언

SOAP 메시지에서 사용되는 <Envelope>, <Header>, <Body> 엘리먼트는 반드시 네임스페이스 선언을 해서 다른 마크업과 구별해야 된다.

SOAP 메시지에서 사용되는 네임스페이스 선언 방법 :

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
~
</soap:Envelope>

SOAP 1.11.2 메시지는 서로 다른 네임스페이스를 사용하고 있기 때문에, 이를 이용하면 응용 프로그램은 SOAP 메시지에 대한 버전을 확인할 수 있다. SOAP 메시지와 응용 프로그램 간의 SOAP 버전이 다른 경우에는 'version mismatch'라는 오류를 출력한다.

SOAP 1.1의 네임스페이스
http://schemas.xmlsoap.org/soap/envelope/

SOAP 1.2
의 네임스페이스

http://www.w3.org/2001/06/soap-envelope

2.2 <Envelope> 엘리먼트

SOAP 메시지의 루트 엘리먼트이다.

<Header> 엘리먼트와 <Body> 엘리먼트를 자식 엘리먼트로 가질 수 있다.

<Header>는 선택적으로 사용되지만, <Body> 엘리먼트는 반드시 한 개가 있어야 한다.

 

2.3 <Header> 엘리먼트

 

SOAP 메시지에 인증, 트랜잭션 관리, 지불 서비스와 같은 부가 정보를 덧붙이는 방법을 제공한다.

<Header> 엘리먼트는 자식 엘리먼트를 가질 수 있는데, 이 자식 엘리먼트를 헤더 엔트리라고 한다.

헤더 엔트리는 최종 수신자에서 처리될 수도 있지만 여러 중간 메시지 전달자를 거치면서 처리될 수 있기 때문에 헤더 엔트리를 구분하기 위해서 반드시 네임스페이스 접두사를 사용한 QName으로 기술해야 한다.

헤더 엔트리의 자식 엘리먼트는 QName으로 기술하지 않아도 무방하다.

헤더 엔트리의 루트 엘리먼트는 다음과 같은 2가지 속성을 가질 수 있다.

속성 설명 속성값
actor 헤더 엔트리를 처리할 액터를 지정 actor URI
mustUnderstand 헤더 엔트리의 내용을 반드시 처리해야 됨을 지정 0, 1

 

(1) actor 속성

SOAP 메시지는 최종 목적지에 도착하기 전까지 여러 중간 메시지 전달자(actor, intermediary)지나갈 수 있다.

 

<용어>

SOAP 중개자(actor, intermediary)
SOAP 메시지를 수신할 수도 있고 전달할 수도 있는 서비스(application)로서, SOAP이 사용하는 프로토콜에 상관없이 메시지는 message path라는 경로로 전달된다. message path는 메시지 중간 단계와 최종 수신 단계에서 사용된다.

이때 누가 헤더 엔트리를 처리할 것인가를 지정하기 위해서 actor 속성을 사용하며, 만약에 actor 속성이 없으면 SOAP 메시지의 최종 수신자가 헤더 엔트리를 처리하게 된다.

 

actor 속성값은 URI가 올 수 있으며, 그 중 특별한 역할을 하는 URI가 있는데, actor의 값이http://schemas.xmlsoap.org/soap/actor/next로 지정된 경우에는 해당 헤더 엔트리는 메시지가 지나가는 경로에서 첫 번째로 나오는 중개자가 처리하게 된다.

 

actor 속성을 사용한 SOAP 메시지

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope
          xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
          <soap:Header>
                    <m:authentication xmlns:m="http://cs.knou.ac.kr/soap/authentication"
                                                  soap:actor="http://www.knou.ac.kr/authentication">
                              <userID>gomdoli</userID>
                              <password>gmd123</password>
                    </m:authentication>
          </soap:Header>
          <soap:Body>
          ~
          </soap:Body>
</soap:Envelope>

<m:authentication> 엘리먼트를 처리하는 액터로서 "http://www.knou.ac.kr/authentication" URI에 있는 액터가 지정되었다. 전달된 SOAP 메시지는 신원을 확인하기 위해 신원 확인 웹 서버로 전달되어 사용자 신원을 확인한 후, 기존의authentication이라는 헤더 엔트리는 인증 확인 코드를 담은 다음과 같은 메시지로 변환되어 반환된다.

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope
          xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
          <soap:Header>
                    <m:authentication xmlns:m="http://cs.knou.ac.kr/soap/authentication">
                    <m:auth_code>Efakun149fnaslkDa</m:auth_code>
                    </m:authentication>
          </soap:Header>
          <soap:Body>
          ~
          </soap:Body>
</soap:Envelope>
 
(2) mustUnderstand 속성

mustUnderstand 속성은 헤더 엔트리의 내용이 반드시 처리되어야 하는 지의 여부를 알려주기 위해서 사용되는 속성으로, 속성값이 1로 지정된 경우에는 지정된 수신자가 반드시 헤드 엔트리를 처리해야만 한다. 그렇지 않은 경우에는 SOAP 메시지의 처리가 실패하게 된다. 속성이 지정되지 않은 경우에는 기본적으로 0인 것으로 간주한다.

 

mustUnderstand 속성 사용

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope
          xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
          <soap:Header>
                    <m:authentication xmlns:m="http://cs.knou.ac.kr/soap/authentication"
                                                                      soap:mustUnderstand="1">
                              <userID>gomdoli</userID>
                              <password>gmd123</password>
                    </m:authentication>
          </soap:Header>
          <soap:Body>
          ~
          </soap:Body>
</soap:Envelope>
위의 메시지에서는 mustUnderstand 속성을 사용했기 때문에 SOAP 메시지를 처리하기 전에 반드시 <authentication> 엘리먼트를 통해 인증을 받아야 한다.

2.4 <Body> 엘리먼트

<Body> 엘리먼트는 최종 수신자가 수신해야 할 궁극적인 정보를 포함하고 있는 것으로 SOAP 스펙에서의 바디에 대한 정의는 다음과 같다.

 

"SOAP 바디는 메시지 최종 수신자에게 전달하고자 하는 필수 정보를 제공하기 위한 간단한 방법을 제시한다. 바디 요소의 전형적인 쓰임은 RPC 호출 내용을 XML로 인코딩하고 오류 혹은 상태 정보를 전달하는 것이다."

 

바디의 일반적인 사용 목적은 RPC나 오류 출력이지만, 정보 전달을 위해서 XML 형식의 어떠한 정보도 포함할 수 있다.

<Body> 엘리먼트의 자식 엘리먼트를 바디 엔트리라고 부른다.

최종 수신자는 요청한 원격 프로시저를 찾을 때 네임스페이스 이름을 사용하기 때문에 바디 엔트리는 반드시 QName으로 기술되어야 한다. 이때 네임스페이스는 최종 수신자가 정의한 원격 프로시저에 대한 네임스페이스 이름을 사용해야 한다.

SOAP <Body>가 포함하는 바디 엔트리의 자식 엘리먼트는 네임스페이스로 구별될 필요가 없다.

 

바디 부분에 원격 프로시저 호출을 포함한 SOAP 메시지

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope
          xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
          xmlns:ns0="http://cs.knou.ac.kr/grad/" >
          <soap:Header>
                    <m:authentication xmlns:m="http://cs.knou.ac.kr/soap/authentication">
                              <userID>gomdoli</userID>
                              <password>gmd123</password>
                    </m:authentication>
           </soap:Header>
          <soap:Body>
                    <ns0:enrollment>
                              <String_0>웹서비스특론</String_0>
                              <Int_0>2005</Int_0>
                    </ns0:enrollment>
          </soap:Body>
</soap:Envelope>
바디 엔트리는 반드시 QName으로 기술되어야 하기 때문에 ns0라는 네임스페이스 접두사를 가지고 있.
 
바디 부분의 <ns0:enrollment> 엘리먼트는 대학원 과목 수강 정보를 저장하는 enrollment() 메소드를 원격으로 호출하는 역할을 수행하며, <String_0><Int_0> 엘리먼트의 내용에는 각각 수강 과목과 수강년도에 대한 정보가 기술되어 있다.
이와 같은 요청 SOAP 메시지에 대해서 최종 수신자는 다음과 같은 식으로 메시지를 해석하여 enrollment() 메소드를 수행할 것이다.

enrollment("웹서비스특론“, 2005);

 
2.5 <Fault> 엘리먼트
SOAP <Fault> 엘리먼트는 송신자가 수신자에게 보내는 SOAP 메시지를 처리할 때 생길 수 있는 오류 혹은 상태 정보를 응답 SOAP 메시지 내에 기술해서 송신자에게 전달하기 위해서 사용한다.

<Fault> 엘리먼트는 <Body> 엘리먼트의 자식 엘리먼트로 작성되며, 응답 SOAP 메시지 내에 오직 하나만 존재할 수 있으며, 자식 엘리먼트로는 <faultcode>, <faultstring>, <faultactor>, <detail> 과 같은 4가지의 엘리먼트를 가지며 다음과 같은 형식으로 사용된다.

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope
          xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
          <soap:Body>
                    <soap:Fault>
                              <faultcode>오류코드</faultcode>
                              <faultstring>오류에 대한 설명</faultstring>
                              <faultactor>오류가 발생한 액터</faultactor>
                              <detail>오류에 대한 추가적인 설명</detail>
                    </soap:Fault>
          </soap:Body>
</soap:Envelope>
 
(1) <faultcode> 엘리먼트
<faultcode>4가지 요소 중에서 유일한 필수 요소이며, 오류를 처리하는 응용 프로그램에게 쉽게 오류를 판별할 수 있는 방법을 제공한다. SOAP 스펙에서는 몇 가지의 오류코드를 다음과 같이 정의하고 있다.
오류코드 이름 설명
VersionMismatch SOAP 메시지의 <Envelope> 엘리먼트가 포함한 버전정보가 다른
경우
MustUnderstand mustUnderstand 속성값이 1인 헤더 엔트리를 처리하지 못했을 경우
Client SOAP 메시지가 올바른 정보를 가지고 있지 않거나 부적합해서 처리
할 수 없는 경우
Server SOAP 메시지가 가지는 내용에 의한 것이 아니라 서버 측에서 메시지
를 처리하는 도중에 오류가 발생하는 경우

위의 오류코드는 soap:Server와 같은 형태로 반드시 "soap"과 같은 네임스페이스 접두사를 붙여서 사용해야 한다.

위의 일반적인 오류코드는 구분자 ‘.’을 통해 좀 더 세부적인 오류코드로 다음과 같이 확장될 수 있다.

일반적인 오류코드.세부적인 오류코드

: Client.Authentication와 같은 오류 메시지를 사용하면 SOAP 메시지가 인증(Authentication)을 위해 적절한 정보를 찾지 못했다는 것을 알 수 있다.

표준 SOAP 오류코드 중에서 MustUnderstand에 해당하는 오류가 발생하였을 때, SOAP Fault 구조에서는 구체적으로 어떤 SOAP 헤더 엔트리에서 문제가 발생했는 지를 표현할 수가 없다. 따라서 이를 위SOAP 1.2에서는 MisUnderstand를 통해 어떤 헤더 엔트리 처리에서 오류가 발생했는 지를 정의할 수 있다.

(2) <faultstring> 엘리먼트

오류에 대해서 사람이 이해할 수 있도록 간략한 설명을 삽입하고자 할 때 선택적으로 사용할 수 있는 엘리먼트이다. 이것을 통해 오류가 발생한 원인에 대한 설명을 덧붙일 수 있다.

(3) <faultactor> 엘리먼트
SOAP 메시지가 다수의 중개자를 거치는 동안, 그 중 하나에서 오류가 발생하면 <faultactor>는 어떤 액터에 의해서 오류가 발생했는 지를 식별할 수 있는 URI를 담게 된다.
SOAP 메시지의 최종 수신자가 아닌 중간 전달자들은 오류가 발생하면 반드시 SOAP <Fault> 엘리먼트 안에 <faultactor> 엘리먼트를 가져야한다. 하지만 <faultactor>가 생략되면 최종 수신자에서 처리 도중에 발생한 오류라고 가정을 하기 때문에 최종 수신자는 반드시 가질 필요가 없다.

(4) <detail> 엘리먼트

오류가 SOAP 바디에 직접 연관이 있을 경우에 사용한다. 이 엘리먼트는 <Body> 엘리먼트가 바르게 처리되지 않은 경우에는 반드시 사용한다. 반면 SOAP 헤더에 관한 오류가 발생했을 때에는 생략가능하.

SOAP Fault<detail> 엘리먼트를 갖지 않는 것은 오류의 원인이 바디와 상관이 없다는 것을 의미한. 이를 통해 <Body>가 올바르게 처리되었는 지 여부를 확인할 수 있다.


3. SOAP 메시지 교환 및 처리

 

3.1 SOAP 메시지 교환 모델

SOAP 메시지 교환은 송신자(sender)와 수신자(receiver)로 구성되며, 메시지는 송신자에서 수신자로 단방향으로 이동한다. SOAP 메시지 수신자를 종점(endpoint)이라고 부르기도 하며, 메시지를 확인하고 처리하는 것은 모두 종점에서 해야 할 일이다.

 

종점은 메시지를 수신하는 역할도 하지만 다시 다른 종점으로 SOAP 메시지를 보내는 송신자 역할도 할 수 있기 때문에 여러 개의 종점으로 이루어져 있는 메시지 체인을 형성한다. 따라서 다음과 같은 여러 가지의 메시지 교환 모델을 통하여 더 복잡한 동작을 만들어 낼 수 있다.

(1) 요청과 응답 모델

현재 가장 많이 사용되고 있는 메시지 교환 모델로서, 송신자는 원격 프로시저 호출을 위한 요청 SOAP 메시지를 보내고 수신자는 원격 프로시저를 실행한 후 결과를 응답 SOAP 메시지로 보내준다.

그림 2. 요청과 응답 모델

(2) 재귀적 모델

송신자와 수신자가 하나의 사이클을 형성하는 메시지 교환 형태이다.

그림 3. 재귀적 모델

 

(3) 브로드캐스트 모델

단일 송신자가 단방향으로 여러 개의 수신자에게 메시지를 보내는 형태를 의미한다.

그림 4. 브로드캐스트 모델

 

3.2 SOAP 메시지 처리 과정

 

(1) 중개자의 역할

처리할 헤더 엔트리를 찾기 위해 actor 속성과 중개자의 URL 비교

일치하는 엔트리가 존재하면, mustUnderstand 속성값이 1인지를 확인

mustUnderstand 속성값이 1인 경우에는 반드시 헤더 엔트리를 처리하고, 처리할 수 없으면 MustUnderstand라는 오류코드로 <Fault> 엘리먼트를 설정한다.

성공적으로 헤더 엔트리가 처리되면, 해당 헤더 엔트리를 제거한 후 다음 목적지로 SOAP 메시지를 전송

 

(2) 최종 수신자의 역할

SOAP 메시지에서 처리되지 않는 헤더 엔트리와 바디 엔트리 부분을 모두 처리한다.

처리 결과 또는 오류 내용을 포함한 응답 SOAP 메시지를 송신자에게 전송


4. SOAP 인코딩

 

SOAP 메시지는 모두 문자로 구성된 XML 문서이기 때문에 메시지를 처리하는 응용 프로그램이 SOAP 메시지의 데이터를 임의의 데이터 형으로 처리할 수도 있지만, SOAP 메시지에 표기한 데이터 형에 맞게 처리하도록 해야 한다.

이와 같이 특정 프로그래밍 언어로 작성된 응용 프로그램에서 SOAP 메시지를 생성할 때 프로그래밍 언어에서 사용된 데이터형을 SOAP 메시지에서 어떻게 표기해야 되는 지를 정해 놓은 방법을 “SOAP 인코딩이라고 일컫는다.

그림 5. SOAP 인코딩

4.1 encodingStyle 속성

송신자는 메시지를 생성할 때 SOAP 스펙에서는 encodingStyle 속성을 통해 SOAP 메시지에서 쓰이는 데이터를 위한 인코딩 규칙 즉 어떤 표기법을 이용해서 데이터형을 지정했는 가를 명시해야 한다.

encodingStyle 속성의 속성값으로 지정된 데이터형 표기법의 적용범위는 encodingStyle 속성을 가지고 있는 엘리먼트의 하위 자손 엘리먼트로 국한된다. 따라서 일반적으로는 SOAP 메시지 전체를 적용 범위를 설정하기 위해서 전역 속성으로, <Envelope> 엘리먼트에 기술한다.

encodingStyle의 값이 빈문자로도 올 수 있는데, 이는 자식 요소에 어떠한 인코딩 규칙도 적용하지 않겠다는 것을 의미하고, SOAP 스펙에서 제공하는 기본적인 인코딩 규칙 이외에도 사용자 자신만의 인코딩 규칙을 정의해서 적용할 수 있다.

 

수신자는 encodingStyle 속성값으로 언급되어 있는 데이터형 표기법에 따라 SOAP 메시지에 포함된 데이터를 해석하고 적절한 프로그래밍 데이터형으로 변환해서 사용한다.

 

encodingStyle 속성의 사용 방법 (SOAP 1.1 스펙에 기술되어 있는 데이터형 표기법을 사용하도록 지정하는 경우)

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope
          xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
          soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding">
          ~
</soap:Envelope>
SOAP 스펙은 SOAP 메시지에서 어떻게 데이터가 인코딩되는 지 정의하고 있는데, 이를 위해 XML 키마의 데이터 타입을 사용하고 있다. XML 스키마에서 제시하는 단순 타입(Simple Type)과 복합 타입(Compound Type)의 데이터를 그대로 SOAP 메시지의 데이터 타입으로 인코딩하는 방법을 사용하고 있다.

4.2 단순 타입

단순 타입이란 프로그래밍 언어의 기본 데이터형으로서, XML 스키마 언어에서 정의된 내장 단순 타입으로 표기하기 위해서 ‘xsi:type’ 속성을 다음과 같이 사용한다.

<엘리먼트 xsi:type="xsd:데이터형">데이터</엘리먼트>

xsiXML 스키마 인스턴스에 대한 네임스페이스 선언시 사용한 접두사이고, xsdXML 스키마 언어에 대한 네임스페이스 선언시 사용한 접두사이다.

<참고 사이트>

XML 스키마 언어의 내장 단순 타입
http://www.w3.org/TR/xmlschema-2/
단순 타입의 데이터를 원격 프로시저 호출 시 메소드의 인자로 사용하는 방법
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope
          xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
          xmlns:xsd="http://www.w3.org/2001/XMLSchema"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:enc="http://schemas.xmlsoap.org/soap/encoding"
          xmlns:접두사=“원격 프로시저의 네임스페이스 이름
          soap:encodingStyle="http://shemas.xmlsoap.org/soap/encoding" >
          <soap:Body>
                    <접두사:메소드명>
                              <인자명 xsi:type="xsd:데이터형">데이터</인자명>
                              <인자명 xsi:type="xsd:데이터형">데이터</인자명>
                              ~
                    </접두사:메소드명>
          </soap:Body>
</soap:Envelope>

<메소드명><인자명> 엘리먼트는 수신자에서 실행될 원격 프로시저를 정의해 놓은 웹 서비스 명세서WSDL 문서에서 사용된 이름을 반드시 사용해야 한다.

: enrollment 메소드의 인자로 단순 타입을 사용해서 호출 요청하는 SOAP 메시지

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope
          xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
          xmlns:xsd="http://www.w3.org/2001/XMLSchema"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:enc="http://schemas.xmlsoap.org/soap/encoding"
          xmlns:ns0="http://cs.knou.ac.kr/grad/"
          soap:encodingStyle="http://shemas.xmlsoap.org/soap/encoding" >
          <soap:Body>
                    <ns0:enrollment>
                              <String_0 xsi:type="xsd:string">웹서비스특론</String_0>
                              <Int_0 xsi:type="xsd:int">2005</Int_0>
                    </ns0:enrollment>
          </soap:Body>
</soap:Envelope>
위의 메시지와 같이 단순 타입을 사용하기 위해 직접 XML 스키마의 데이터 타입을 사용할 수도 있지, soap이라는 네임스페이스를 통해서도 XML 스키마의 모든 단순 타입을 사용할 수 있다. 이는 soap 스키마와 네임스페이스는 XML 스키마의 모든 단순 타입을 다시 선언하고 있기 때문이다. 따라서 위의 메시지에서 진하게 밑줄로 표시된 부분을 동일한 의미를 갖도록 다음과 같이 다시 선언할 수 있다.
<soap:string id="String_0">웹서비스특론</soap:string>
<soap:int id="Int_0">2005</soap:int>

SOAP 메시지의 수신자는 다음과 같은 방식으로 데이터의 비직렬화(deserialization)를 수행한다.

String String_0 = "웹서비스특론";
int Int_0 = 2005;

그리고 enrollment() 메소드를 다음과 같은 형태로 실행할 것이다.

enrollment(String_0, Int_0);

 

4.3 복합 타입

SOAP 1.1에서는 배열(array)과 구조체(struct)가 복합 타입으로 구분한다. SOAP 스펙에서는 이 두가지 타입을 다음과 같이 정의하고 있다.

구조체는 유일한 접근자 이름을 가지는 두 개 이상의 요소를 담을 수 있는 복합 타입으, 접근자에 의해 서로 다른 값을 할당받을 수 있다.
 
배열은 동일한 접근자 이름을 가지는 두 개 이상의 요소를 담을 수 있는 복합 타입으로순서에 의해 서로 다른 값을 할당 받을 수 있다.

구조체 타입과 배열 타입의 예

구조체 타입 배열 타입
<book>
<title>웹서비스</title>
<author>홍길동</author>
</book>
<student>
<name>이순신</name>
<name>강감찬</name>
</student>

 

(1) 배열 표기법

SOAP 메시지에서의 배열 표기 문법

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope
          xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
          xmlns:xsd="http://www.w3.org/2001/XMLSchema"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:enc="http://schemas.xmlsoap.org/soap/encoding"
          soap:encodingStyle="http://shemas.xmlsoap.org/soap/encoding" >
          <soap:Body>
                    <엘리먼트명 id="배열식별자"
                                                            xsi:type="enc:Array" enc:arrayType="데이터형[n]">
                    <item>인덱스 0의 값</item>
                    ~
                    <item>인덱스 n의 값</item>
          </엘리먼트명>
          </soap:Body>
</soap:Envelope>

id 속성은 원격 프로시저 호출 시에 이 배열을 참조하여 사용할 수 있도록 배열 식별자를 지정해 준다.

xsi:type 속성은 이 엘리먼트가 배열형임을 나타내기 위해서 사용되고, enc:arrayType 속성은 데이터형과 배열의 크기를 지정하기 위한 것이다.

배열은 다차원일 수도 있다. 다차원일 경우에는 arrayType 속성을 지정할 때 다음과 같이 크기를 표시하면 된다.

<엘리먼트명 id="배열식별자"
xsi:type="enc:Array" enc:arrayType="xsd:string[2,3]">
<item>r1c1</item>
<item>r1c2</item>
<item>r1c3</item>
<item>r2c1</item>
<item>r2c2</item>
<item>r2c3</item>
</엘리먼트명>

원격 프로시저 호출 시 메소드의 인자로 배열을 사용하는 방법

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope
          xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
          xmlns:xsd="http://www.w3.org/2001/XMLSchema"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:enc="http://schemas.xmlsoap.org/soap/encoding"
          xmlns:접두사=“원격 프로시저의 네임스페이스 이름
          soap:encodingStyle="http://shemas.xmlsoap.org/soap/encoding" >
          <soap:Body>
                    <접두사:메소드명>
                    <          배열참조변수명 href="#배열식별자"/>
                    </접두사:메소드명>
                    <엘리먼트명 id="배열식별자"
                                        xsi:type="enc:Array" enc:arrayType="데이터형[n]">
                              <item>인덱스 0의 값</item>
                              ~
                              <item>인덱스 n의 값</item>
                    </엘리먼트명>
          </soap:Body>
</soap:Envelope>

<메소드명><배열참조변수명> 엘리먼트는 수신자에게 실행될 원격 프로시저를 정의해 놓은 WSDL 문서에서 사용된 이름을 반드시 사용해야 한다. <배열참조변수명> 엘리먼트의 href 속성에는 인자로 사용할 배열의 식별자를 ‘#’기호와 함께 기술해 주면 된다.

: 여러 과목을 동시에 저장하는 enrollment2() 메소드를 호출 요청하는 SOAP 메시지

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope
          xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
          xmlns:xsd="http://www.w3.org/2001/XMLSchema"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:enc="http://schemas.xmlsoap.org/soap/encoding"
          xmlns:ns0="http://cs.knou.ac.kr/grad/"
          soap:encodingStyle="http://shemas.xmlsoap.org/soap/encoding" >
          <soap:Body>
                    <ns0:enrollment2>
                              <arrayCourse href="#coursearray"/>
                    </ns0:enrollment2>
                    <array id="coursearray"
                                                  xsi:type="enc:Array" enc:arrayType="xsd:string[3]">
                              <item>웹서비스특론</item>
                              <item>컴퓨터구조특론</item>
                              <item>지능형정보처리시스템</item>
                    </array>
          </soap:Body>
</soap:Envelope>

위와 같은 SOAP 메시지의 수신자는 배열 데이터를 다음과 같이 해석하여 enrollment2() 메소드를 실행할 때 인자로 사용할 것이다.

String arrayCourse[] = new String[3];
arrayCourse[0] = "웹서비스특론"
arrayCourse[1] = "컴퓨터구조특론"
arrayCourse[2] = "지능형정보처리시스템"

enrollment2(arrayCourse);

(2) 구조체 표기법

SOAP 메시지에서 구조체 자료의 표기 방법

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope
          xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
          xmlns:xsd="http://www.w3.org/2001/XMLSchema"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:enc="http://schemas.xmlsoap.org/soap/encoding"
          xmlns:접두사=“구조체에 대한 네임스페이스 이름
          soap:encodingStyle="http://shemas.xmlsoap.org/soap/encoding" >
          <soap:Body>
                    <엘리먼트명 id="식별자" xsi:type="접두사:구조체명">
                              <멤버변수명 xsi:type="데이터형"></멤버변수명>
                              ~
                              <멤버변수명 xsi:type="데이터형"></멤버변수명>
                    </엘리먼트명>
          </soap:Body>
</soap:Envelope>
원격 프로시저 호출 시 메소드의 인자로 구조체를 사용하는 방법
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope
          xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
          xmlns:xsd="http://www.w3.org/2001/XMLSchema"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:enc="http://schemas.xmlsoap.org/soap/encoding"
          xmlns:접두사1=“원격 프로시저의 네임스페이스 이름
          xmlns:접두사2=“구조체의 네임스페이스 이름
          soap:encodingStyle="http://shemas.xmlsoap.org/soap/encoding" >
          <soap:Body>
                    <접두사1:메소드명>
                              <구조체변수명 href="#식별자"/>
                    </접두사1:메소드명>
                    <엘리먼트명 id="식별자"
                                                                                                              xsi:type="접두사2:구조체명">
                              <멤버변수명 xsi:type="데이터형"></멤버변수명>
                              ~
                              <멤버변수명 xsi:type="데이터형"></멤버변수명>
                    </엘리먼트명>
          </soap:Body>
</soap:Envelope>
xsi:type 속성에는 구조체명을 기술해 준다. 이때 주의할 점은 웹 서비스 명세서인 WSDL 문서에 기술되어 있는 구조체 대한 네임스페이스를 선언한 후 접두사를 붙여 QName 형태로 기술해야 한다.

: 구조체 형태로 과목 정보를 받아 저장하는 enrollment3() 메소드를 호출 요청하는 SOAP 메시지

(자바에서 구조체란 class형을 말한다. Courses.class에는 2개의 멤버 titleyear로 구성되어 있다고 가정)

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope
          xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
          xmlns:xsd="http://www.w3.org/2001/XMLSchema"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:enc="http://schemas.xmlsoap.org/soap/encoding"
          xmlns:ns0="http://cs.knou.ac.kr/grad/"
          xmlns:ns1="http://cs.knou.ac.kr/grad/"
          soap:encodingStyle="http://shemas.xmlsoap.org/soap/encoding" >
          <soap:Body>
                    <ns0:enrollment3>
                              <gradCourse href="#ID1"/>
                    </ns0:enrollment3>
                    <course id="ID1"
                                        xsi:type="ns1:Courses">
                              <title xsi:type="string">웹서비스특론</title>
                              <year xsi:type="int">2005</year>
                    </course>
          </soap:Body>
</soap:Envelope>

위와 같은 SOAP 메시지에 대한 최종 수신자는 다음과 같이 해석해서 해당 메소드를 실행할 것이다.

Courses gradCourse = new Courses();
gradCourse.setTitle("웹서비스특론");
gradCourse.setYear(2005)

enrollment3( gradCourse );

5. SOAP 메시지 전송 프로토콜 : HTTP

 

5.1 전송 프로토콜

송신자가 작성한 SOAP 메시지를 수신자에게 전달하기 위해서는 전송 프로토콜이 필요하며, SOAP과 전송 프로토콜을 접목시키는 작업을 바인딩이라고 한다. 이론적으로 SOAP 메시지는 SMTP, FTP 등 어떤 전송 프로토콜과도 바인딩될 수 있지만, HTTP(Hyper Text Transfer Protocol)가 실제로 가장 많이 사용되는 전송 프로토콜이다. 따라서 요청 SOAP 메시지는 요청 HTTP에 실어 보내고 응답 SOAP 메시지는 응답 HTTP에 담겨서 전송된다.

 

HTTP는 텍스트 기반의 매우 간단한 프로토콜이다. 이러한 특징은 HTTP가 다양한 단말 환경에서 작동하도록 하는 중요한 요인이다. HTTP는 미리 정의된 몇 가지 메시지 타입에 따라 클라이언트와 서버간에 작동하는데, 이것은 클라이언트의 요청(request)과 서버의 응답(response)으로 구분된다.

 

5.2 HTTP 특징

HTTPTCP/IP의 상위 수준 프로토콜로서 다음과 같은 2가지의 특징을 지닌다.

연결지향(connection-oriented)

클라이언트의 요청이 서버에 의해서 처리되고 그 응답이 클라이언트에게 다시 전송되는 동안 연결이 계속해서 유지된다

무상태(stateless)

요청에 대한 서버의 처리가 완료되면 클라이언트에 대한 어떠한 정보도 가지지 않은 채 연결이 즉시 해제되기 때문에, 클라이언트가 다시 서버에 연결되면 새로운 클라이언트 접속으로 간주한다.

 

5.3 HTTP 구조

HTTP는 그림에서 보는 바와 같이 시작 행, 헤더, 본문의 세 부분으로 구성된다. 요청 HTTP와 응답 HTTP의 구조는 기본적으로 동일하나 시작행을 이루는 요소가 다르다.

그림 6. HTTP 구조

 

(1) 요청 시의 시작 행 구성 요소

Method Request-URI HTTP/Version

Method : 요청방식 기술

          - GET 방식: Request-URI에 요청하는 내용 및 전달할 데이터를 포함해서 보내는 방식

          - POST 방식: Request-URI에는 요청하는 내용만 포함시키고 전송할 데이터는 본문 부분에 포함시 켜서 전송하는 방식

          - GET 방식은 전송되는 양에 제한이 있기 때문에 파일 전송이나 SOAP 메시지 전송은 반드시 POST 방식으로 수행

 

Request-URI : 다운로드 할 문서 또는 서버 측에서 실행할 컴포넌트를 지정

HTTP/Version : 클라이언트가 이용하는 HTTP의 버전을 기술

 

(2) 응답 시의 시작 행 구성 요소

HTTP/Version 응답코드 응답코드설명

HTTP/Version : 서버가 이용하는 버전을 기술

응답코드 : 클라이언트 요청에 대한 성공 여부를 나타내는 코드를 기술하는 부분으로, 코드의 종류는 다음과 같다.

200~299 : 클라이언트 요청이 성공적으로 처리되었다
400~499 : 클라이언트 측 오류로 인해 처리되지 않았다
500~599 : 서버 측 오류로 인해 처리되지 않았다.

 

(3) 헤더

본문에는 포함되지 않는 부가적인 정보를 다음과 같은 형태로 기술한다.

헤더명: 헤더값

 

대표적인 부가적인 정보

요청 HTTP
Host
Content-Type
Content-Length
User-Agent
Cookie
서버측 주소
본문 내용의 MIME 타입
본문 내용의 크기
클라이언트 프로그램 종류
쿠키명1=쿠기값1;쿠키명2=쿠키값2
 
응답 HTTP
Content-Type
Server
Set-Cookie
본문 내용의 MIME 타입
서버 프로그램 종류
쿠키명1=쿠기값1;쿠키명2=쿠키값2

 

(4) 본문

헤더 마지막 부분과 본문 부분은 빈 공백으로 구분되며, 본문 부분에는 전송하고자 하는 데이터를 담고 있다. 따라서 SOAP 메시지가 바로 본문 부분에 담겨져서 전송된다.

 

SOAP 메시지를 담고 있는 요청 HTTP는 다음과 같은 형태를 지닌다.

POST /rpcrouter HTTP/1.1
Content-Type: text/xml; charset="utf-8"
Content-Length: nnnn
SOAPAction: ""

<soap:Envelope
          xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
          xmlns:xsd="http://www.w3.org/2001/XMLSchema"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:enc="http://schemas.xmlsoap.org/soap/encoding"
          xmlns:ns0="http://cs.knou.ac.kr/grad/"
          soap:encodingStyle="http://shemas.xmlsoap.org/soap/encoding" >
          <soap:Body>
                    <ns0:enrollment>
                              <String_0 xsi:type="xsd:string">웹서비스특론</String_0>
                              <Int_0 xsi:type="xsd:int">2005</Int_0>
                    </ns0:enrollment>
          </soap:Body>
</soap:Envelope>

위와 같은 요청 SOAP 메시지에 대해서 웹 서비스 시스템은 다음과 같은 SOAP HTTP 응답를 반환할 수 있다.

HTTP/1.1 200 OK
Content-Type: text/xml; charset="utf-8"
Content-Length: nnn

<soap:Envelope
          xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
          xmlns:xsd="http://www.w3.org/2001/XMLSchema"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:enc="http://schemas.xmlsoap.org/soap/encoding"
          xmlns:ns0="http://cs.knou.ac.kr/grad/"
          soap:encodingStyle="http://shemas.xmlsoap.org/soap/encoding" >
          <soap:Body>
                    <ns0:enrollmentResponse>
                              <result xsi:type="xsd:string">2005학년도 웹서비스특론 등록 완료</result>
                    </ns0:enrollmentResponse>
          </soap:Body>
</soap:Envelope>

 

참고: SOAPAction 헤더

원격 프로시저 호출 요청 SOAP 메시지가 HTTP를 통해서 방화벽을 그대로 통과하게 되, 익명의 사용자가 아주 중요한 원격 프로시저를 호출할 수 있기 때문에 보안상 심각한 문제를 야기할 수 있다.

따라서, SOAP 스펙에서는 요청 HTTP 헤더 부분에 SOAPAction이라는 헤더를 새로 정의함으로써 이런 문제를 다루고 있다.

HTTP를 전송 프로토콜로 사용해서 SOAP 클라이언트가 SOAP 메시지를 전송할 때 SOAPAction 헤더를 사용해서 메시지의 용도를 밝혀야 한다. 그러면 방화벽은 이를 이용해서 SOAP 메시지를 적절히 걸러낼 수가 있다.

일반적으로 SOAPAction 헤더값으로는 URI를 사용하게 되며, 헤더에 공백 문자열을 사용할 수 있는데 이것은 단순히 SOAP 메시지임을 뜻하는 것이다. 이런 경우 방화벽은 Request-URI를 검사해서 요청 HTTP를 통과시킬 것인지를 결정한다.

정리

웹 서비스에서 응용 프로그램 사이에 공유되는 데이터 형식을 정의하는 프로토콜로서, XML 형식을 따르며 웹 서비스 기본 스택에서 전송 네트워크 바로 위에 위치하는 XML 메시징 스택에 속한다.

SOAP은 플랫폼에 독립적인 XML 형식의 프로토콜을 사용함으로써, 기존의 분산 시스템의 프로토콜에서 문제가 되었던 이기종간의 데이터 교환 문제를 해결할 수 있다.

 

SOAP 메시지는 <Envelope>, <Header>, <Body> 부분으로 구성되며, 반드시 네임스페이스를 선언해서 다른 마크업과 구별해야 한다.

 

<Header> 엘리먼트는 actor 속성과 mustUnderstand 속성을 가진다.

 

<Fault> 엘리먼트는 메시지 처리 과정에서 발생하는 오류 혹은 상태 정보를 기술하기 위해서 사용되는 것으로, <faultcode>, <faultstring>, <faultactor>, <detail>과 같은 4개의 자식 엘리먼트를 가진.

 

SOAP 인코딩은 프로그래밍 언어에서 사용된 데이터 타입을 SOAP 메시지에서 표기하는 방법을 의미하며, 단순 타입과 복합 타입으로 구분할 수 있다.

 

HTTP는 웹 서비스의 전송 네트워크로서 웹 서비스에 사용되는 XML 메시지를 전달하는 역할을 한. HTTP와 같은 표준 전송 네트워크를 사용함으로써 다양한 플랫폼 간에 통신이 가능하다.

 

'정보과학 > 웹서비스특론' 카테고리의 다른 글

웹 서비스 시스템 개발  (1) 2023.09.09
SOAP API  (0) 2023.09.08
XML 스키마 (2)  (0) 2023.09.06
XML 스키마 (1)  (0) 2023.09.05
XML 네임스페이스  (0) 2023.09.05