|
제목에서와 같이 이번장은 JMS를 이용한 비동기식 웹 서비스를 구현하는데 JMS및 MDB(Message Driven Bean)에 대한 얘기는 하지 않는다. 본문을 보고싶다면
http://www.ibm.com/developerworks/kr/library/ws-tip-altdesign1/ 를 참조하고 나는 부가적인 설명을 하면서 정리해나가도록 하겠다. 우선 웹서비스에서는 기본적인 4가지의 메세지 교환패턴(MEP)이 있는데 다음과 같다.
Figure1. 비동기식 쿼리패턴 ![]() Figure1의 flow는 다음과 같다. 1. 요청자는 서비스 공급자(Service Provider)에게 요청을 제출한다. 서비스 공급자는 메시지를 대기열에 넣고 (queue) 요청자(Requester)가 요청 상태를 확인할 때 사용할 수 있는 코릴레이션 ID를 리턴한다. 여기서 코릴레이션 ID는 활성화된 즉, 실행중인 서비스에 대한 식별키라고 보는 것이 맞을 것이다. 2. 요청 프로세서는 요청을 대기열에서 빼고(dequeue) 이를 처리한다. 일반적으로 이 요청 프로세싱은 장기 실행이 다. 일단 프로세싱이 완료되면 프로세서(Processor)는 응답 메시지를 대기열에 넣는다. 3. 어떤 지점에서 그 요청에 대한 응답이 준비가 되면 요청자는 서비스 공급자에게 요청한다. 응답이 대기열에 들어가 면 공급자는 요청자에게 응답을 리턴한다. 응답을 사용할 수 없다면 공급자는 이를 요청자에게 보고한다. 요청자는 요청을 취소하거나 계속 기다릴 수 있다. 선택된 기간 동안, 응답이 사용 가능하게 될 때까지 공급자는 폴링(polling) 한다. 간단하게 관련지식을 알았으면 예제로 들어가 보자. [ 서비스 인터페이스 설계 ] List1. AsyncService.wsdl <?xml version="1.0" encoding="UTF-8"?> <wsdl:definitions targetNamespace="http://one.wspattern.developerworks.ibm.com" xmlns:impl="http://one.wspattern.developerworks.ibm.com" xmlns:intf="http://one.wspattern.developerworks.ibm.com" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <wsdl:types> <schema targetNamespace="http://one.wspattern.developerworks.ibm.com" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:impl="http://one.wspattern.developerworks.ibm.com" xmlns:intf="http://one.wspattern.developerworks.ibm.com" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <complexType name="ResponseCheck"> <sequence> <element name="correlationID" nillable="true" type="xsd:string"/> </sequence> </complexType> <element name="ResponseCheck" nillable="true" type="impl:ResponseCheck"/> <complexType name="Response"> <sequence> <element name="type" type="xsd:int"/> <element name="correlationID" nillable="true" type="xsd:string"/> <element name="refresh" type="xsd:int"/> <element name="a" nillable="true" type="xsd:string"/> <element name="b" nillable="true" type="xsd:string"/> <element name="c" nillable="true" type="xsd:string"/> </sequence> </complexType> <element name="Response" nillable="true" type="impl:Response"/> <complexType name="Request"> <sequence> <element name="a" nillable="true" type="xsd:string"/> <element name="b" nillable="true" type="xsd:string"/> <element name="c" nillable="true" type="xsd:string"/> </sequence> </complexType> <element name="Request" nillable="true" type="impl:Request"/> </schema> </wsdl:types> <wsdl:message name="submitRequestRequest"> <wsdl:part name="request" type="intf:Request"/> </wsdl:message> <wsdl:message name="checkResponseResponse"> <wsdl:part name="checkResponseReturn" type="intf:Response"/> </wsdl:message> <wsdl:message name="checkResponseRequest"> <wsdl:part name="check" type="intf:ResponseCheck"/> </wsdl:message> <wsdl:message name="submitRequestResponse"> <wsdl:part name="submitRequestReturn" type="intf:Response"/> </wsdl:message> <wsdl:portType name="AsyncService"> <wsdl:operation name="checkResponse" parameterOrder="check"> <wsdl:input message="intf:checkResponseRequest" name="checkResponseRequest"/> <wsdl:output message="intf:checkResponseResponse" name="checkResponseResponse"/> </wsdl:operation> <wsdl:operation name="submitRequest" parameterOrder="request"> <wsdl:input message="intf:submitRequestRequest" name="submitRequestRequest"/> <wsdl:output message="intf:submitRequestResponse" name="submitRequestResponse"/> </wsdl:operation> </wsdl:portType> <wsdl:binding name="AsyncServiceSoapBinding" type="intf:AsyncService"> <wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name="checkResponse"> <wsdlsoap:operation soapAction=""/> <wsdl:input name="checkResponseRequest"> <wsdlsoap:body namespace="http://one.wspattern.developerworks.ibm.com" use="literal"/> </wsdl:input> <wsdl:output name="checkResponseResponse"> <wsdlsoap:body namespace="http://one.wspattern.developerworks.ibm.com" use="literal"/> </wsdl:output> </wsdl:operation> <wsdl:operation name="submitRequest"> <wsdlsoap:operation soapAction=""/> <wsdl:input name="submitRequestRequest"> <wsdlsoap:body namespace="http://one.wspattern.developerworks.ibm.com" use="literal"/> </wsdl:input> <wsdl:output name="submitRequestResponse"> <wsdlsoap:body namespace="http://one.wspattern.developerworks.ibm.com" use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="AsyncServiceService"> <wsdl:port binding="intf:AsyncServiceSoapBinding" name="AsyncService"> <wsdlsoap:address location="http://localhost:8088/ws/services/AsyncService"/> </wsdl:port> </wsdl:service> </wsdl:definitions> List1은 비동기 응답-요청이 적용된 WSDL파일이다. 해석하는 것이 가능한가? 가능하면 OK~~ 계속진행해도 좋다. 가능하지 않다면 기본학습을 하고 읽자. 으~~ 간만에 이어서 쓰게 된다. 회사일이 너무 바빠서.... 위에 적힌 WSDL을 가지고 Tmax JEUS에서 실행시켜보기로 하겠다. 우선 Tmax Technet에 가서 JEUS 5 Fix#18을 받은 후 적절한 디렉토리에 설치한다. 또한 JMaker 최신 Version을 받아서 설치하자. JMaker는 JEUS환경의 Eclipse기반 개발툴이다. 손쉽게 웹서비스를 구축할 수 있기 때문에 WSDL2JAVA, JAVA2WSDL, java mapping 파일 같은 중노동(?)을 하지 않아도 된다......고 Tmax에서는 얘기하겠지만 천만의 말씀, 만만의 콩떡이다.말그대로 JEUS환경에 적절한 WSDL을 갖고는 손쉽게 구축이 가능한데 위와 같이 비 JEUS 친화적인(?) WSDL로는 generate된 java파일과 여러 Descriptor파일들의 설정이 맞지 않는다. 우선 WSDL2JAVA와 같은 command로 웹서비스를 생성시켜 직접 Deploy해보는것도 학습에는 여러 도움이 된다. 그래야 JMaker생성시킨 엉뚱한 결과물에도 대처가 가능하다. 어찌됐든 개발의 편의성이 있는것만은 사실이다. 하기 귀찮은 사람은 다음 파일을 다운받아서 Deplo시키자.wsexer002ear.ear 이 파일은 JMaker에서 생성시킨파일을 토대로 약간의 수정작업을 거친 ear파일이다. 열어보면 알겠지만 위의 WSDL과 차이점이 있는걸 발견할 수 있다. 여하튼 이런 얘기는 여기까지 하기로 하고 직접 작성한 것이든 위의 파일이든 JEUS 웹어드민을 통해 Deploy시키자.
|
![]() by lovemade |