일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Source
- 문서
- Eclipse
- Docker
- jpa
- error
- AJAX
- Core Java
- IntelliJ
- MySQL
- Tomcat
- Spring Boot
- ubuntu
- oracle
- JDBC
- spring
- Thymeleaf
- PostgreSQL
- Open Source
- 설정
- MSSQL
- myBatis
- git
- STS
- 오픈소스
- JavaScript
- maven
- SpringBoot
- Exception
- Python
- Today
- Total
헤르메스 LIFE
[Ajax] Ajax로 SOAP 웹 서비스 호출하기, Part 2: 웹 서비스 클라이언트 확장하기 본문
[Ajax] Ajax로 SOAP 웹 서비스 호출하기, Part 2: 웹 서비스 클라이언트 확장하기
헤르메스의날개 2011. 8. 22. 15:38본 시리즈 Part 1에서는, RPC 인코딩 및 document-literal 스타일 요청이 가능한 SOAP 웹 서비스 클라이언트를 제공하는 크로스 브라우저 JavaScript를 소개했다. 요청 및 응답 핸들러 지원, 커스텀 XML 직렬화/비직렬화, SOAP Headers 지원이 이 클라이언트에 포함되었다. 이 모든 것들이 WS-Addressing과 WS-ResourceFramework에 포함되어 있다.
ws.js
(Part 1)에 정의된 기본 객체들은 다음과 같다.
- WS.Call: XMLHttpRequest를 래핑하는 웹 서비스 클라이언트
- WS.QName: XML 전용 이름 (XML Qualified Name) 구현
- WS.Binder: 커스텀 XML 직렬화/비직렬화 베이스
- WS.Handler: 요청/응답 핸들러 베이스
- SOAP.Element: XML DOM을 래핑하는 기본 SOAP 엘리먼트
- SOAP.Envelope: SOAP.Element를 확장하는 SOAP Envelope 객체
- SOAP.Header: SOAP.Element를 확장하는 SOAP 헤더 객체
- SOAP.Body: SOAP.Element를 확장하는 SOAP 바디 객체
- XML: XML을 핸들링 하는 크로스 플랫폼 유틸리티 메소드
이 객체들 중에서, 다섯 가지는 WS-Addressing과 WS-ResourceFramework 구현에 중요하다: WS.QName
, SOAP.Element
, WS.Handler
, WS.Binder
, WS.Call
첫번째 기술자료에서 이러한 객체들의 기본 기능들을 복습하기 바란다.
이 글에서는 두 개의 새로운 JavaScript 파일들을 소개한다. 첫 번째는 WS-Addressing을 지원하는 객체를 정의하고 ( wsa.js
), 두 번째는 WS-ResourceFramework의 기본 구현을 지원하는 객체를 정의한다. ( wsrf.js
).
그림 1. Web Services JavaScript Library를 사용하여 웹 브라우저 내에서 Web Service Resource Framework 서비스 호출하기
wsa.js
에 정의된 기본 객체들은 다음과 같다.
- WSA.EndpointReference: WS-Addressing EndpointReference 객체.
- WSA.EndpointReference.ReferenceParameters: WS-Addressing EPR 레퍼런스 매개변수용 컨테이너.
- WSA.EndpointReference.Binder: WSA.EndpointReference 객체용 XML 직렬화/비직렬화
- WSA.MessageContext: WS-Addressing SOAP 메시지 헤더 메타데이터용 컨테이너
- WSA.Handler: WS-Addressing SOAP 메시지 헤더를 SOAP Envelope에 삽입하는 요청 핸들러.
wsrf.js
에 정의된 기본 객체는 다음과 같다.
- WSRF.Request.GetResourceProperty: WS-ResourceFramework GetResourceProperty 연산용 래퍼.
- WSRF.Request.GetMultipleResourceProperties: WS-ResourceFrame GetMultipleresourceProperties 연산용 래퍼.
- WSRF.Resource: WS-ResourceFramework 연산을 호출하는 클라이언트 인터페이스.
배워야 할 새로운 JavaScript 객체들이 너무 많은 것 같지만, 이들이 제공하는 API는 여러분이 실제로 웹 서비스를 호출할 때 해야 할 많은 작업들을 줄여준다. 예를 들어, Listing 8을 보면, 이 API로 WS-ResourceFramework 호환의 웹 서비스를 단 몇 줄의 코드로 호출할 수 있다는 것을 알 수 있다.
Web Services Addressing 스팩은 어드레싱 정보를 SOAP Envelope에 삽입하는 메커니즘을 정의한다. WS-Addressing의 핵심에는 EndpointReference
로 알려진 객체가 있는데, 이는 특정 웹 서비스 인스턴스에 대한 레퍼런스 겸 디스크립션 역할을 한다. (Listing 1) WS-Addressing 스팩은 SOAP Envelope 내에서 어드레싱 정보를 직접 전달하는데 사용되는 많은 SOAP 메시지 헤더들을 정의한다.
wsa.js
JavaScript 라이브러리는 WS-Addressing EndpointReference와 SOAP 메시지 헤더 엘리먼트에 대한 기본적인 지원을 구현하는 많은 객체들을 제공한다.
Listing 1. WS-Addressing EndpointReference
<EndpointReference xmlns="http://www.w3.org/2005/08/addressing"> <Address>http://www.example.org/services/HelloWorld</Address> <ReferenceParameters> <abc:foo xmlns:abc="urn:foo">This is a test</abc:foo> </ReferenceParameters> </EndpointReference> |
WSA.EndpointReference 객체는 WS-Addressing EndpointReferences를 나타내는데 사용된다. (Listing 2) 이 코드를 위의 XML과 비교해 보면, API가 어떻게 작동하는지를 이해할 수 있을 것이다.
Listing 2. WSA.js로 EndpointReference 구현하기
var epr = new WSA.EndpointReference( "http://www.example.org/services/HelloWorld"); var epr_rp = epr.create_reference_parameters(); epr_rp.create_child( new WS.QName('foo','urn:foo','abc')). set_value('This is a test'); |
WSA.EndpointReference용 API는 현재 WS-Addressing 정보 모델에 정의된 대로 Address와 ReferenceParameters를 지원한다. Metadata 프로퍼티는 현재 구현되어있지 않다. 이는 이 글에서 구현할 클라이언트의 기본 기능에는 중요하지 않다.
WS-Addressing SOAP 메시지 헤더는 웹 서비스 클라이언트에 의해 서비스로 보내지는 SOAP Envelope에 설정된다. ws.js
JavaScript 라이브러리에 정의된 WS.Call 객체는 SOAP.Envelope와의 작동 상세를 숨기기 때문에, WS.Handler를 사용하여 올바른 헤더를 삽입한다.
웹 서비스 클라이언트는 모든 요청, 응답, 에러 시 WS.Handler 객체의 메소드를 호출한다. WS-Addressing 구현의 경우, 메시지로 삽입 될 정보를 포함하고 있는 WSA.MessageContext 객체를 사용하는 WSA.Handler가 제공된다. (Listing 3)
Listing 3. WS-Addressing 콘텍트스와 핸들러 사용하기
var address = 'http://www.example.com/services/HelloWorld'; var ctx = new WSA.MessageContext(); ctx.to = new WSA.EndpointReference(address); ctx.replyto = new WSA.EndpointReference(WSA.ANONYMOUS); ctx.action = address + '#SayHello' var handler = new WSA.Handler(); handler.set_context(ctx); var call = new WS.Call(''); call.add_handler(handler); |
WSA.MessageContext 객체에 대한 프로퍼티는 WS-Addressing SOAP 메시지 헤더에 상응한다.
- to: WSA.EndpointReference 객체. 이것의 Address는 메시지의 목적지를 구분하는 절대 URI를 지정한다.
- from: 메시지의 센더(sender)를 구분하는 WSA.EndpointReference 객체.
- replyto: 응답이 전달될 장소를 구분하는 WSA.EndpointReference 객체.
- faultto: 오류가 전달될 장소를 지정하는 WSA.EndpointReference 객체.
- action: 메시지가 실행하기로 한 액션을 구분하는 절대 URI.
- messageid: 메시지를 식별하는 절대 URI.
- relatesto: 관련 메시지들을 구분하는 URI 쌍들의 어레이. 이 쌍의 첫 번째 URI는 관계 유형을 구분한다. 두 번째 URI는 관련 메시지의 고유 Message ID를 지정한다.
WSA.Handler가 웹 서비스를 호출하는데 사용되는 WS.Call 객체로 등록되면, WS.Call 객체는 모든 요청 시 핸들러를 호출하면서, 이것을 SOAP.Envelope 객체에 대한 레퍼런스로 전달한다. 이 핸들러는 WSA.MessageContext에서 정보를 가져와서 알맞은 헤더를 메시지로 삽입한다. (Listing 5)
Web Services Resource Framework은 웹 서비스 표준을 사용하여 Stateful 리소스들의 인스턴스에 액세스 하여 조작하는 규약을 정의한다. 개별 리소스들이 WS-Addressing EndpointReferences에 의해 구분 및 참조된다. 많은 공통 연산들이 이 리소스의 프로퍼티를 검색 또는 수정하는데 사용된다.
wsrf.js
JavaScript 라이브러리는 GetResourceProperty와 GetMultipleResourceProperties 연산을 지원하는 Web Services Resource Framework의 부분적인 구현을 제공한다. 이 API는 ws.js
와 wsa.js
API를 기반으로 구현되며, 포괄적인 WS-ResourceFramework 구현을 제공하는 것 보다 두 스크립트의 사용을 설명하는데 치중한다.
WS-ResourceFramework 연산들은 document-literal SOAP 요청으로서, 지정된 Resource 인스턴스로 향한다. 대상 리소스는 WS-Addressing EndpointReference에 의해 구분된다. (Listing 4)
Listing 4. A WSRF EndpointReference
<EndpointReference xmlns="http://www.w3.org/2005/08/addressing"> <Address>http://localhost:9080/SoapAjax2/services/DeviceService</Address> <ReferenceParameters> <abc:DeviceID xmlns:abc="urn:deviceservice">ABC123</abc:DeviceID> </ReferenceParameters> </EndpointReference> |
wsa.js
에서 정의된 메커니즘을 사용하여 SOAP Envelope 내에서 표현될 때, WSRF EndpointReference 내의 정보는 SOAP 메시지 헤더의 형태를 취한다. (Listing 5)
Listing 5. WSRF GetResourceProperty Request
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> <Header> <To xmlns="http://www.w3.org/2005/08/addressing"> http://localhost:9080/SoapAjax2/services/DeviceService</To> <abc:DeviceID xmlns="urn:deviceservice">ABC123</abc:DeviceID> </Header> <Body> <GetResourceProperty xmlns="http://docs.oasis-open.org/wsrf/rp-2" xmlns:ns="urn:foo">ns:bar</GetResourceProperty> </Body> </Envelope> |
wsrf.js
에서 제공되는 API는 WS-ResourceFramework 웹 서비스들과 인터랙션을 실행하는데 필요한 SOAP Envelope와 WS-Addressing 헤더들과 작동하는 모든 상세들을 숨긴다. 이 코드를 보면 작동 방법에 있어 중요한 측면을 보게 될 것이다.
Listing 6은 WSRF GetResourceProperty 연산용 래퍼 객체이다. 이 래퍼는 wsrf.js
라이브러리에 의해 내부적으로 사용되고 SOAP Envelope를 구현하고 연산에 필수적인 XML을 구현하는 기본 메커니즘을 포함하고 있다. 이 객체는 ws.js
에서 제공되는 SOAP.Element 와 SOAP.Envelope API를 활용한다. 래퍼 객체의 초기화 동안 전달된 "qname" 매개변수는 요청되고 있는 프로퍼티의 XML Qualified 이름이다.
Listing 6. WSRF GetResourceProperty 요청 래퍼
WSRF.Request.GetResourceProperty = Class.create(); WSRF.Request.GetResourceProperty.prototype = { initialize : function(qname) { this.envelope = new SOAP.Envelope(); this.set_qname(qname); }, set_qname : function(qname) { var body = this.envelope.create_body(); var method = body.create_child( WSRF.Request.QNAME_GETRESOURCEPROPERTY); if (!qname.namespace) qname.namespace = ''; if (!qname.prefix) qname.prefix = 'ns'; method.declare_namespace(qname); method.set_value(qname.value_of()); } }; |
Listing 7에는 WSRF.Resource
객체에서 온 코드 스니펫이 포함된다. 여러분이 보는 것은 WS.Call 객체의 생성, 올바른 SOAP 메시지 헤더를 설정하는데 사용될 WSA.Handler 객체 준비, WSRF.Request.GetResourceProperty 래퍼 객체의 생성, 웹 서비스 연산의 호출이다.
Listing 7. WSRF GetResourceProperty 호출하기
get_resource_property : function(qname, callback) { var call = new WS.Call(this.address); var handler = new WSA.Handler(); var wsactx = new WSA.MessageContext(this.epr); handler.set_context(wsactx); call.add_handler(handler); var req = new WSRF.Request.GetResourceProperty(qname); call.invoke(req.envelope, callback); } |
WS-ResourceFramework Web service에 대한 GetResourceProperty 연산을 호출하려면, 이 애플리케이션은 검색된 프로퍼티를 구분하는 대상 WS-Resource 와 WS.QName 객체용 EndpointReference를 제공하면 된다. (Listing 8)
Listing 8. 정리
var ADDRESS = 'http://localhost:9080/SoapAjax2/services/DeviceService' function getDeviceName(deviceID, container) { var epr = new WSA.EndpointReference(ADDRESS); var epr_rp = epr.create_reference_parameters(); epr_rp.create_child( new WS.QName( 'DeviceID', 'urn:deviceservice')).set_value(deviceID); var res = new WSRF.Resource(ADDRESS, epr); res.get_resource_property( new WS.QName('DeviceName','urn:deviceservice'), function(call,envelope) { $('soap').innerHTML = arguments[2].escapeHTML(); } ); } |
Listing 8은 HTML 페이지 내의 어느 곳에서나 호출될 수 있도록 WS-Resource에 대한 호출을 함수로 래핑한다. Listing 9는 id라고 하는 인풋 필드에서 device id로 전달되는 버튼을 제공하고 응답 SOAP Envelope를 result라고 하는 div 엘리먼트에 디스플레이 한다.
Listing 9. getDeviceName 호출하기
<input value="Invoke the Web Service" type="button" onclick="getDeviceName($('id').value,$('result'))" /> |
이 글에서는 본 시리즈 Part 1에 소개된 Ajax 웹 서비스 클라이언트가 확장되어 Web Services Addressing과 Web Services Resource Framework 같은 웹 서비스 표준을 지원하는 방법을 살펴보았다. 다음 글에서는, Web Services Description Language 지원에 대해 살펴보도록 하겠다.
설명 | 이름 | 크기 | 다운로드 방식 |
---|---|---|---|
Sample project | ws-wsajax2code.zip | 14KB | HTTP |
교육
- Ajax로 SOAP 웹 서비스 호출하기 -- 이 시리즈의 모든 파트 보기.
- 동적 자바 애플리케이션 구현 (한글) -- Philip McCarthy의 자바 개발자를 위한 Ajax 소개 (한국 developerWorks, 2005년 9월).
- JavaScript Framework
- XMLHttpRequest API
- Document Object Model을 활용하여 고급 웹 애플리케이션 만들기 -- (developerWorks, 2004년 2월).
- Mozilla Web Services
- Web Services Resource Framework -- OASIS Web Services Resource Framework
- Web Services Addressing
- 표준 로드맵 -- SOA와 웹 서비스 개발용 표준과 스팩.
- 아키텍처: 미래를 위한 구현 -- developerWorks의 아키텍처 존.
- SOA와 웹서비스
토론
James Snell은 IBM Emerging Technologies Toolkit 팀의 멤버이다. 이머징 웹 서비스 기술 및 표준 분야에서 오랜 시간 경력을 쌓았고, Atom 1.0 스팩에 기여했다. http://www.ibm.com/developerworks/blogs/dw_blog.jspa?blog=351에서 weblog를 관리하고 있다.
'JSP&JavaScript&HTML' 카테고리의 다른 글
Common URL Escape Characters (0) | 2012.04.04 |
---|---|
자바스크립트의 여러형태의 함수를 클래스 처럼 사용하기 (0) | 2011.11.25 |
[Ajax] Ajax로 SOAP 웹 서비스 호출하기, Part 1: 웹 서비스 클라이언트 구현하기 (0) | 2011.08.22 |
[Ajax] 자바 개발자를 위한 Ajax: Ajax와 Direct Web Remoting (한글) (0) | 2011.08.22 |
[Ajax] XMLHttpReqeust 레퍼런스 (0) | 2011.08.22 |