IT_Architecture/Architecture

SOA - JAVA로 SOAP 구축하기 (1) ~ (3)

JJun ™ 2011. 7. 12. 15:53

-----------------------------------------------------------------------------------------------

 출처: http://ammoguy.springnote.com/

-----------------------------------------------------------------------------------------------

 

이번 시간에는 WS Communication Protocol 중 현재 가장 널리 사용되고 있는 SOAP에 대한 기본적인
구조에 대해서 알아보겠다.


SOAP 은 서로 다른 플랫폼의 XML 분산컴퓨팅을 위한 기반기술이다. 분산컴퓨팅이라는 말처럼 SOAP
내에는 분산컴퓨팅을 가능하게 하기 위한 기반기술이 XML Document로 정의 되어지고 SOAP Message는 SOAP처리기라는 SOAP엔진에 의해 처리된다. 일반적으로 많이 쓰이는 엔진이 Axis 이고 해당 엔진은
많은 Vendor들에 의해 어플리케이션 서버와 같은 제품에 탑재되어 있다. SOAP자체는 일반 application이나 비즈니스 로직의 개발자나 업무사용자를 위한 기술이 아니라, 저 수준의 분산시스템 개발자를 위한 것이다.

 

SOAP을 이해할 때 중요한 포인트는 단순히 WS의 통신 Protocol이라는 개념으로 이해하지 말고
분산 컴퓨팅을 위한 통신 Protocol 이라는 개념을 항상 주지해야 한다는 것이다.


DS process간의 통신(interprocess communication)은 DS의 핵심이다.
DS는 수천 수만의 process들이 Network에 편재해 있고 이러한 process들을 어떠한 표준적인 방법으로
접근하지 않는다면 많은 어려움이 뒤따를 것이다.

 

그래서 나타난 것이 표준적인 Rule인 Protocol 이 등장했고 다음이 가장 널리 사용되는 Protocol이다.


 

  1. Remote Procedure Call ( RPC)
  2. Remote Method Invocation (RMI)
  3. Message-Oriented Middleware (MOM)
  4. Stream

 

이에 대한 자세한 사항은 Distributed System이라는 Category에서 다루기로 하겠다.

여기서 잠깐, 우선 일반 서적에서 얘기하고 있는 SOAP의 기본적인 Framework 부터 살펴보자.

 

 

 

[ SOAP Envelope Framework ]

 

SOAP 에서 가장 중요한 부분은 Envelope Framework이다.

메시지에 무엇이 있는지와 이를 어떻게 처리하는지를 설명하는 Framwork을 정의하는 인벨롭(envelope), 애플리케이션 정의의(application-defined) 데이터 유형의 인스턴스를 표현하는 인코딩 규칙,

원격 프로시져 호출과 응답을 나타내는 규칙 등 세 부분으로 구성된 XML 기반의 프로토콜이다

 

 

Figure1. 기본 구조




 

SOAP은 크게 세부분, Envelope, Header, Body로 나뉜다.

  • [ Envelope ] SOAP Message 의 root 로서 전체 Message에 대한 Encoding Style을
    정의 할 수 있다.
  • [ Header ] Envelope 의 Child Element로서 optional하고 1회이상 쓰일 수 있다. Header는 Security, Transaction, Reliable Message, QoS 등과 같은 추가적인 기능을 포함할 수 있는
    확장 메커니즘을 제공한다. 또한 SOAP Node간의 각종 Spec과 관련된 협약의 준수여부를
    나타내는 mustUnderstande 속성을 제공한다.  
  • [ Body ] 실질적인 Data가 들어가는 곳이다. 다른말로 하면 Body Element내에는 최종 수신자에게 보내져야 하는 정보가 들어가 있다. 어떤 서비스를 이용할 것인지, 요청과 응답 Data 는
    무엇인지 등등

 

 

 

그럼 Header와 Body에 대해서 좀더 자세히 알아보자.

 

 

 

[ Header ]

 

SOAP Spec은 message path에 서 처리되어야하는 rule을 정의할 수 있는데 처리되어야 하는 rule을
정의하는 곳이 바로 Header block이다. 여기서 message path는 SOAP message가 최초의 sender로 부터 최종 receiver 까지 가는데 거쳐야 하는 경로를 말한다.

 

message path상에 등록되어 있는 SOAP Node들을 Intermediaries라 하는데 spec에서는 어떠한 intermediary가 특정 header block을 처리할 것인지를 정의하고 있다.

 

SOAP은 Network상의 SOAP application들 간의 message를 상호 교환하기 위한 protocol이다.

여기서 SOAP application이라 함은 SOAP message를 생성하거나 처리하기 위한 일종의 software이다.

예를 들어 여느 java application 혹은 J2EE component가 JAX-RPC를 사용한다면 일종의 SOAP application이라고 볼 수 있다. SOAP message는 message path를 경유하는데 모든 SOAP message는 최초의 message를 생성하는 initial sender로 부터 시작해서 최종 message를 처리하는 ultimate receiver로 끝이 난다.

 

 

Figure2. The SOAP Message Path



SOAP message가 message path를 경유할 때 SOAP header block은 지정된 SOAP node에 의해 intercept되서 해당 header block을 처리하게 되는데 SOAP Node들은 sender 와 receiver의 역할을
병행한다. 여기서 잠시 예를 들어보자.

 

Figure3. The Message Path of the Purchase-Order SOAP Message.

 

Figure3 은 Purchase Order라는 SOAP message가 Customer, Sales, Accounts, Inventory, Shipping SOAP nodes경유하는 message path이다. Intermediaries는 SOAP body block를 처리하거나 수정할 수 없고 단지 header block을 처리하는 역할을 한다. 실질적인 SOAP message를 살펴보도록 하자.

 

 

List1. The process-by Header block.

 

<?xml version="1.0" encoding="UTF-8"?>


          <soap:Envelope



           xmlns:soap="
http://schemas.xmlsoap.org/soap/envelope/"


           xmlns:mi="
http://www.Monson-Haefel.com/jwsbook/message-id"


           xmlns:proc="
http://www.Monson-Haefel.com/jwsbook/processed-by">


            <soap:Header>



              <mi:message-id>11d1def534ea:b1c5fa:f3bfb4dcd7:-8000</mi:message-id>



              <proc:
processed-by>


                <node>



                  <time-in-millis>1013694680000</time-in-millis>



                  <identity>http://www.customer.com</identity>



                </node>



                <node>



                  <time-in-millis>1013694680010</time-in-millis>



                  <identity>http://www.Monson-Haefel.com/sales</identity>



                </node>



                <node>



                  <time-in-millis>1013694680020</time-in-millis>



                  <identity>http://www.Monson-Haefel.com/AR</identity>



                </node>



                <node>



                  <time-in-millis>1013694680030</time-in-millis>



                  <identity>http://www.Monson-Haefel.com/inventory</identity>



                </node>



                <node>



                  <time-in-millis>1013694680040</time-in-millis>



                  <identity>http://www.Monson-Haefel.com/shipping</identity>



                </node>



              </proc:processed-by>



            </soap:Header>



            <soap:Body>



                <!-- Application-specific data goes here -->



            </soap:Body>



          </soap:Envelope>
          
 

 

List1에서 process-by 라는 Header Block은 SOAP Message를 처리한 SOAP node들에 대한 기록을
남긴 것이다.

 

이 말은 Message Path에 있는 SOAP node들이 SOAP Message를 처리하면서 SOAP Message에 내용을 추가하거나 뺄 수도 있다는 얘기이다. 그럼 SOAP node들은 어떤 Header block을 처리해야 하는지 어떻게 알까? 이에 대해 SOAP Spec은 특정 Header Block을 처리하는 node를 식별하기 위한 actor 속성을 도입했다.

 

actor 속성은 역할에 대한 URI 형태의 식별자이다. 그래서 해당 SOAP Message가 Message Path를
경유할 때 해당 actor의 역할을 하기로 되어 있는 SOAP node에서는 처리되어지고 다른 node에서는
무시된다.

 

 

List2. The actor Attribute. 

 

          <?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:mi="http://www.Monson-Haefel.com/jwsbook/message-id"
xmlns:proc="http://www.Monson-Haefel.com/jwsbook/processed-by">
<soap:Header>
<mi:message-id soap:actor="http://www.Monson-Haefel.com/logger" >
11d1def534ea:b1c5fa:f3bfb4dcd7:-8000
</mi:message-id>
<proc:processed-by>
<node>
<time-in-millis>1013694680000</time-in-millis>
<identity>http://www.customer.com</identity>
</node>
</proc:processed-by>
</soap:Header>
<soap:Body>
<!-- Application-specific data goes here -->
</soap:Body>
</soap:Envelope>

 

  

List2를 보면 soap:actor="http://www.Mansoa-Haefel.com/logger" 을 볼 수가 있는데
actor에 대한 식별자를 URI로 식별하고 있으며 해당 actor에 대한 처리 노드는 해당 처리 절차를 진행한다.

 

일반적인 관점으로 SOAP Header를 봤을때 SOAP Header는 meta-data를 처리하기 위한 뛰어난 확장성을
지닌다. Security, Transaction, QoS, Message Persistence, Routing 등 실제 Data 와는 상관이 없는 meta-data를 처리하기 위한 기반을 제공하고 있다. 물론 범용적으로 사용되는 표준은 OASIS같은 단체에서 관장하고 있으며 Domain에 custom한 방식으로도 사용될 수 있다.

 

 

 

 

[ BODY ]

 

SOAP BODY에는 웹 서비스간 교환하려는 실질적인 Data, 어느 operation을 call 할 것인지, 넘겨줄 parameter는 무엇인지, return 값은 무엇인지, error발생시 fault 메세지 등, 상호운영상에 교환되는
Data가 들어간다. Header Element는 선택적으로 사용될 수 있지만 Body Element는 필수적인 요소이다.

 

또한 Message Path에서 Body Element를 처리할 수 있는 SOAP node는 Ultimate Node 뿐이다.

상호운영 시 error가 발생해 Body Element에 적용되는 fault message를 제외하고 SOAP은 Body의 Contents가 well-formed XML이라면 어떠한 XML message가 적용되더라도 상관하지 않는다.
물론 웹서비스간 상호운영성에 맞는 Rule를 적용해야 되겠지만서도.......

 

웹서비스는 상호운영하는데 있어 XML 기반의 Protocol을 사용한다. 즉. Text기반의 Message로 상호간의 원하는 일을 수행한다는 것이다. 그래서 SOAP에서는 4종류의 messaging mode를 지원한다.

 

  1. RPC/Literal
  2. Document/Literal
  3. RPC/Encoded
  4. Document/Encoded

 

messaging mode는 messaging style(RPC/Document)과 encoding style (Section 5/Literal)에
의해 정의되는데 여기서는 RPC/Literal과 Document/Literal에 대해서 알아보겠다.

 

Figure 4. Document Literal and RPC Literal


 

 

 

Document / Literal

SOAP Body Element내에 well-formed XML Document가 embed되어 있는것을 말한다.
List3 에서는 namespace가
http://www.Monson-Haefel.com/jwsbook/PO 인 XML Schema 에 따르는
XML Message가 embed 되어 있다.

 

 

List3. A Document Style SOAP Message. 

 

  <?xml version="1.0" encoding="UTF-8"?>


          <soap:Envelope



           xmlns:soap="
http://schemas.xmlsoap.org/soap/envelope/"


           xmlns:mi="
http://www.Monson-Haefel.com/jwsbook/message-id"


           xmlns:proc="
http://www.Monson-Haefel.com/jwsbook/processed-by">


            <soap:Header>



              <!-- Header blocks go here -->



            </soap:Header>



            <soap:Body>



             
<po:purchaseOrder orderDate="2003-09-22"


               xmlns:po="
http://www.Monson-Haefel.com/jwsbook/PO">
         

          
          
                <po:accountName>Amazon.com</po:accountName>
<po:accountNumber>923</po:accountNumber>
...
<po:book>
<po:title>J2EE Web Services</po:title>
<po:quantity>300</po:quantity>
<po:wholesale-price>24.99</po:wholesale-price>
</po:book>
</po:purchaseOrder>
</soap:Body>
</soap:Envelope>

 

 

 

RPC / Literal

주 로 기존의 Component를 web serivice화할때 사용하는 방식으로 RPC Request Message 에는
method 명과 input parameter 명이 오고, RPC Response Message에는 return value와 output parameter or fault message가 온다. 기존의 component로는 servlet, stateless session bean, Java RMI object, CORBA object, DCOM component 등이 있다.

 

 

List4. An RPC/Literal SOAP Request Message

 

    <?xml version="1.0" encoding="UTF-8"?>


          <soap:Envelope



           xmlns:soap="
http://schemas.xmlsoap.org/soap/envelope/"


           xmlns:mh="
http://www.Monson-Haefel.com/jwsbook/BookQuote">


             <soap:Body>



               
<mh:getBookPrice>


                    <isbn>0321146182</isbn>


                </mh:getBookPrice>
   </soap:Body>


          </soap:Envelope>

 

 

 

List4에서는 SOAP Request Method로 getBookPrice를 call 했고 input parameter로 isbn을 넘겨주었다.

 

 

List5. An RPC/Literal SOAP Response Message

 

  <?xml version="1.0" encoding="UTF-8"?>


          <soap:Envelope



           xmlns:soap="
http://schemas.xmlsoap.org/soap/envelope/"


           xmlns:mh="
http://www.Monson-Haefel.com/jwsbook/BookQuote" >


             <soap:Body>



               
<mh:getBookPriceResponse>


                    <result>24.99</result>


                </mh:getBookPriceResponse>
   </soap:Body>


          </soap:Envelope>

 

 

List5 에서는 List4에 대한 응답으로 return value인 result를 반환하였다.

 

 

 

 

[ SOAP Fault ]

 

Message Path에서 어떠한 한 노드에서 error가 발생했다면 해당 SOAP Fault message는
이전 단계의 node로 전송된다. 물론 이러한 방식은 Request / Response Messaging mode에서 발생하며
One-Way mode에서는 fault message를 전송하지 않는다.

 

예를 들어 Message Path상에 있는 3번째 node에서 error발생했다면 이전단계의 node 에게만
fault message가 전송되며 최초의 node에는 message가 전송되지 않는다. fault message를 받은
node는
해당 fault에 대한 적절한 action을 취한 후 최초의 node에게 다른 fault message를 전송한다.

 

SOAP message는 Body Element에 Fault Element를 포함하고 있는데 List6는 이에 대한 예제이다.

 

List6. A SOAP Fault Message.

 

          <?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:mh="http://www.Monson-Haefel.com/jwsbook/BookQuote" >
<soap:Body>
<soap:Fault>
<faultcode>soap:Client</faultcode>
<faultstring>
The ISBN value contains invalid characters
</faultstring>
<faultactor>http://www.xyzcorp.com</faultactor>
<detail>
<mh:InvalidIsbnFaultDetail>
<offending-value>19318224-D</offending-value>
<conformance-rules>
The first nine characters must be digits. The last
character may be a digit or the letter 'X'. Case is
not important.
</conformance-rules>
</mh:InvalidIsbnFaultDetail>
</detail>
</soap:Fault>
</soap:Body>
</soap:Envelope>
 

 

List6 에서 보는 바와 같이 fault message가 생성되었을 때 SOAP message의 Body는 Fault Element 만을 
포함하고 최초 Requester가 기대했던 Response는 포함되지 않는다.
Fault Element 에는 faulcode, faultstring, faultactor, detail element를 child element로 갖는다.
  • faultcode Element
  • faultstring Element
  • faultactor Element
  • detail Element

 

faultcode는 standard code 리스트가 오는데 Client, Server, VersionMismatch, MustUnderstand 등이
있다.
faulstring은 code 와는 달리 가독성이 좋은 fault message 가 온다.

 

faultactor 는 error 가 발생하고 fault 를 생성한 node 가 온다.

detail 은 faultstring 보다 더 자세한 message 가 온다.

 

 


 

 

part2. Axis Overview

SOAP Part1에서는 SOAP에 대한 기본적인 사항을 살펴보았다.

이번 장에서는 SOAP 처리기 라고 알려진 Axis를 살펴보자.

Axis 는 Apache SOAP 프로젝트의 산물이다.

지금까지 크게 2가지의 Version(Axis1.x, Axis2.x)이 나와있으며 Axis2에서는 기존 Axis보다 보다
유연한 구조(module이 쉽게 configuration 될 수 있는),  성능 향상, 비동기 웹 서비스, hot deploy기능 등을 제공하고 있다. W3C에서는 SOAP를 다음과 같이 정의하고 있다.

 

 

SOAP is a lightweight protocol for exchanging structured information in a decentralized, distributed
environment. It is an XML based protocol that consists of three parts: an envelope that defines a
framework for describing what is in a message and how to process it, a set of encoding rules for expressing
instances of application-defined datatypes, and a convention for representing remote procedure calls and responses.

 

 

자세히 설명하자면 SOAP은 분산환경에서 정보의 교환, 즉 웹서비스를 통해 정보를 교환하는 일종의 
XML 기반의 protocol 이며 그 protocol 을 정의하고 있는 SOAP message내에는 무슨 내용이 있으며 
어떻게 message를 처리해야하는지와 encoding rule이 정의되어 있다. 즉 일종의 쌍방(서비스 제공자와
요청자)간의 협약이 맺어져 있어 Axis에서는 해당 SOAP message를 처리한다.


먼저 Apache Axis1의 acchitecture부터 살펴보는것 부터 시작하도록 하자.

 


[ Axis Architecture ]

Figure1. Axis의 기본 구성.

 

  요청자    -------------------------------->   Axis 엔진  <--------------------------> 웹 서비스
                전송매체(HTTP, SMTP, MQ, etc)

 


Figure1 에서 보듯이 Axis는 SOAP message를 HTTP와 같은 전송매체를 통해 받아 웹 서비스에 전달하고 SOAP message로 만들어진 응답을 다시 요청자에게 전달하는 역할을 하는데 다음과 같은 구성 요소들이 어우러져 SOAP을 처리한다.

  • Axis Engine : SOAP 처리기
  • Handler : Axis내부의 기본적인 구성요소로 기본의 백엔드시스템과 Axis를 연결하는 역할을 한다.
  • Chain : 순차적으로 정렬된 Handler들의 모음을 말한다.
  • 전송매체 : SOAP message 흐름이 Axis에 들어오고 나갈 수 있데 하는 메커니즘이다.
  • 구축/설정 : Axis를 통해 웹 서비스를 사용할 수 있도록 하는 수단이다.
  • Seriaizers / Deserializers : Java와 같은 원래 Datatype을 XML로 변환하는 코드/원래 Datatype으로 복원하는 코드이다.

 

 

1. Axis Engine

 

Axis Engine은 여러 컴포넌트, 즉 Handler를 이용해 SOAP message의 흐름을 운영할 뿐만 아니라 
데이터에 대한 순서를 조정하는 책임을 갖는다.

 

 

 

2. Handler & Chain

 

Chain은 순서대로 정렬된 코드형태의 컴포넌트 모음을 말하며 Axis는 정해진 순서대로 이들을 순차적으로 기동하게 되는데, 이렇게 순차적으로 기동되는 컴포넌트들을 가리켜 Handler라고 한다. Handler
웹 서비스 기동 전 후의 message에 대해 추가적인 처리를 수행할 필요가 있을 경우에 사용되는데 logging이나 SOAP Header Block을 처리하기 위해 많이 쓰인다. 그럼 웹 서비스 자체내에서 해당 로직,

즉 바로 앞에서 예로 든 logging이나 SOAP Header block 처리 같은,을 처리하지 않고 Handler 를 사용해서 처리할까? 이유는 웹 서비스 코드는 비즈니스 관점에서 해당 로직만을 처리함으로써 재사용성이 증대되고 각 Handler는 다른작업에 개의치 않고 각자의 고유역할에만 전념할 수 있으므로 코드가 중복되는 여지를
없앨 수 있으며 Axis설정을 통해 새로운 Handler를 추가하거나 삭제하는 식으로 처리가 가능함으로 인해
웹 서비스의 재사용성을 증대시키는 역할을 할 수 있기 때문이다. 만약 Security가  적용되어 있는 기존의 웹 서비스에 RealiableMessage를 적용해야 한다는 요구사항이 발생한다면 기존의 로직을 수정하지 않고
간단하게 RealiableMessage를 처리할 수 있는 Handler를 제작한 후 Axis설정만으로 해당 Handler를 SOAP message처리에 참여시킴으로써  비즈니스 로직을 처리하는 웹 서비스, 보안관련사항을 처리하는 Handler, ReliableMessage를 처리하는 Handler를 각각의 역할만 하도록 제한시킬 수 있는 것이다.

 

그럼 웹 서비스에 대해 정의되어 있는 Handler의 Chain이 모든 요청에 대해 기동할까? 답은 그렇지 않다. 아니 설정을 통해 모든 요청에 대해 기동할 수도 있고 특정부분만이 기동할 수도 있다.

다음 그림을 보도록 하자.

 

 

Figure1. Axis Server Architecture.

 

Figure1 은 Axis의 Server단의 Architecture를 도식으로 표현한 것이다. (Apache Axis 도식 참조)
작은 cylinder는 handler, 작은 cylinder를 감싸는 큰 cylinder는 chain을 나타낸다.


Axis Engine내에 크게 3부분(Transport, Global, Service)으로 구성되어 있는데, Transport 전송매체지정체인으로 특정 전송매체(HTTP, SMTP, MIME...)에 따라 압축 또는 인증 등의 일을 처리하기 위해
정의될 수 있으며, 
Global전역체인으로 웹 서비스의 종류에 상관없이 동일한 처리를 핑요로 하는 경우에 정의된다. 또한 Service특정웹서비스용체인으로 말그대로 특정 웹서비스만을 위한 Chain을 필요로 하는 경우에 정의된다.

 

서비스 내의 Provider는 일종의 Handler인데 backend의 실질적인 웹서비스와 Axis를 잇는 중계자 역할을 한다.

 

즉, SOAP message를 해석해서 필요로 하는 웹 서비스와 관련된 코드 부분을 찾아내어 해당 웹서비스를 기동시키는 역할을 한다. 예를 들어,  XML을 자바객체로 변환한 후 기동시킬 적정한 자바 메소드를 찾아
기동시키고, 가능한 응답 데이터를 XML 형태로 재변환하여 응답 SOAP message에 넣는 일을 한다.  

 

Transport Listener는 request 의 특정 protocol의 data 를 받는 최초 접점으로 해당 protocol-specific data를 Message Object 로 package한 후 Message Object와 각종 properties를 MessageContext 에 설정한 후 MessageContext를 Axis에 전달하는 역할을 한다.

 

장황해서 좀 그런데 다시 정리하면...

 

 1). TransportListener는 요청에 대해 MessageContext Object를 Axis에 전달한다.

 2). 전송매체지정체인이 정의되어 있으면 Chain에 속한 Handler가 기동된다.

 3). 전역체인이 정의되어 있으면 해당 Chain이 기동된다.

 4). 특정웹서비스용체인이 있으면 해당 Chain이 기동된다.

 5). 응답도 이와 비슷한 과정을 거친다........

 

 

 

3. Transport

 

SOAP message를 전달하기 위해 전송매체가 HTTP만이 쓰이는 것은 아니다. SMTP, FTP 등이 사용될 수 있는데 실질적으로 Axis자체는 다중 전송매체를 지원하지는 않는다.

 

무슨말인고 하니, Axis는 들어오는 메세지로 Axis Engine이 호출되어 다시 응답메세지로 보내는 단순한

코드 모음 이상, 이하도 아니며 또한 SOAP message를 기다리는 TransportListener는 Axis Engine의 일부가 아니다.

 

Axis에서는 AxisServlet이라는 TransportListener를 제공하고 만약 특별한 처리가 필요하다면 전송 매체에 맞는 TransportListener를 새로 작성해야만 한다. 따라서 Axis Engine은 TransportListener에 의해
메커니즘이 관리되는데 Axis Engine의 기동(요청마다 Engine이 생성되느냐 혹은 하나의 instance를
공유하느냐), message의
Axis Engine으로의 전달, 어떠한 전송매체가 사용되는지를 Axis Engine에게 통보함으로써 Axis는 설정된 특정전송매체지정체인을 기동하게 된다.

 

 

 

지금까지 Axis Server Architecture를 간략하게 살펴봤는데 Client Architecture는 Provider대신에 Sender라는 전송매체전송자라는 Handler가 대체되고 Transport, Global, Service가 반대로 실행된다고 생각하면 된다. Figure2를 참조하고 자세한 사항은 Apache Axis관련 사이트를 참조하자.

 

Figure2. Axis Client Architecture

 

지금까지 Axis의 기본 Architecture에 대해 살펴보았는데 처음보면 이게 무엇인지 감을 잡기 힘들다.

우선은 이것만 기억하자. Axis는 SOAP message처리 Engine으로 Handler라는 기본 component 들에

의해 message 처리가 이루어진다.

 

 

[ Axis Installation ]

 

여기다 정리하려고 했는데 좋은 문서가 벌써 있는것 같아 해당 문서사용.apache_axis.doc

문서를 보면서 그냥 한번 따라해보면 좋고, 아님 말고, 그래도 한번 해보는 것이 둏지 아니할런지...

 

 


 

 

 

part3. Axis Practice

그럼 실질적으로 한번 구현을 해보자.


SOAP Part2에서 마지막에 첨부시킨 간단한 Hello 웹 서비스를 바탕으로 코드 생성법과 해당 코드에 대한
간단한 설명과 함께....

 

web service를 구현하는 방식에는 2 가지가 있는데

 

1. Java 파일을 coding 한 후 해당 Java 파일을 바탕으로 WSDL 파일을 생성한 후 
   deploy 시키는 방법

 

2. WSDL 파일로 Java파일을 생성한 후 deploy시키는 방법이 있다.

 

 

첫 번째 방법은 서비스 제공자를 만들때 많이 쓰이며 두 번째 방법은 서비스 요청자를 만들 때
많이 쓰인다.

 

 


[ JAVA2WSDL ]

- STEP1. Java Class생성
Java 파일을 작성한 후 웹 서비스를 생성할 때 작성할 Java 파일은 Interface Class 와 해당 Interface 를 Implement 한 Java Class파일 2개가 필요하다라고 문서에는 나와있는데 Interface파일만 있어도 가능하다.

 

다음 파일을 작성 및 complie한 후 적절한 디렉토리에 배치한다.

여기서는 Tomcat\webapps\axis\WEB-INF\classes 에 배치하고 있다.

List1. Java Interface File

 

package webservice.hello;
public interface HelloIF extends java.rmi.Remote {
      public String hello(java.lang.String name) throws java.rmi.RemoteException;
}

 

 

 



- STEP2. 구현된 Class 로 부터 WSDL 생성.

Axis 에서는 Axis.jar파일에 Java2Wsdl 이라는 Class 파일을 제공하고 있다.

해당 파일의 역할은 STEP1 에서 구현한 2개의 Java Class로부터 WSDL파일을 생성하는 것인데
SOAP Part2에서 제공한 문서를 보면 사용법에 대한 자세한 사항이 나와있으니 참조하고 다음과 같이
실행하자.

 

 

java org.apache.axis.wsdl.Java2WSDL -o c:\test\webservice\hello\Hello.wsdl
-l http://localhost:8080/axis/services/Hello -n http://hello.webservice -u literal -pwebservice.hello http://hello.webservice webservice.hello.HelloIF

 

 

부연해서 설명하자면 -l 옵션은 실제 웹 서비스 URL 경로를 지정하는데 WSDL문서를 받은 서비스 요청자
에서 실제 호출경로로 사용하므로 정확히 작성해야 한다.

 

-n 옵션은 WSDL 문서에서 사용할 targetNamespace의 값을 설정한다.

targetNamespace는 해당 문서에서 정의된 XML Element들을 식별하기 위한 것이다.

생성이 잘 되었다면 다음과 같을 것이다.

 


List2. Hello WSDL

 

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions
    targetNamespace="http://hello.webservice"
    xmlns:apachesoap="http://xml.apache.org/xml-soap"
    xmlns:impl="http://hello.webservice"
    xmlns:intf="http://hello.webservice"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/
    xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   

  <!--WSDL created by Apache Axis version: 1.4 Built on Apr 22, 2006 (06:55:48 PDT)-->


   <wsdl:message name="helloResponse">

      <wsdl:part name="helloReturn" type="xsd:string"/>

  </wsdl:message>

   <wsdl:message name="helloRequest">

      <wsdl:part name="in0" type="xsd:string"/>

   </wsdl:message>

   <wsdl:portType name="HelloIF">

      <wsdl:operation name="hello" parameterOrder="in0">

         <wsdl:input message="impl:helloRequest" name="helloRequest"/>

         <wsdl:output message="impl:helloResponse" name="helloResponse"/>


      </wsdl:operation>


   </wsdl:portType>

   <wsdl:binding name="HelloSoapBinding" type="impl:HelloIF">

      <wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>


      <wsdl:operation name="hello">

         <wsdlsoap:operation soapAction=""/>


         <wsdl:input >


            <wsdlsoap:body namespace="http://hello.webservice" use="literal"/>

         </wsdl:input>

         <wsdl:output >


            <wsdlsoap:body namespace="http://hello.webservice" use="literal"/>


         </wsdl:output>


      </wsdl:operation>


   </wsdl:binding>

   <wsdl:service name="HelloIFService">


      <wsdl:port binding="impl:HelloSoapBinding" name="Hello">


         <wsdlsoap:address location="http://localhost:8080/axis/service/Hello"/>


      </wsdl:port>


   </wsdl:service>


</wsdl:definitions>

 

 

 

List 1 의 WSDL파일을 보면 portType의 name이 HelloIF, operation의 name이 hello인데 HelloIF.java의 class명과 method명과 일치함을 알 수 있다. targetNamespace는 -n 옵션에서 정의한 값이 설정되어 있고 location에는 -l 옵션에서 정의한 값이 설정되어 있다. Bold된 단어를 하나씩 비교해가면서 확인해보면
연관성을 알 수 있을 것이다.

 

 

 

- STEP3. WSDD 파일 및 Java 파일 생성

WSDD(Web Service Deployment Descriptor)파일의 용도는 새로운 Handler, Chain 그리고 서비스를
올리기 위해 AdminClient에서 사용하는 설정파일이다. WSDD에 대한 자세한 사항은 해당 사이트를
참조하도록 하자. AdminClient는 관리툴로서, Handler나 Chain같은 Axis리소스를 올리거나 내릴 때
사용한다.

 

 

cmd#> java org.apache.axis.wsdl.WSDL2Java -o d:\ -d Application -s d:\Hello.wsdl

 


http://ws.apache.org/axis/java/reference.html#DeploymentWSDDReference

 

여기서는 d:\ 디렉토리에 wsdd파일 및 Java파일을 생성했다. 생성된 파일목록은 다음과 같다.

 

deploy.wsdd
undeploy.wsdd
HelloIF.java
HelloIFService.java
HelloIFServiceLocator.java
HelloSoapBindingImpl.java
HelloSoapBindingStub.java

 

 

java 파일에 대한 자세한 설명은 J2EE Web Service에서 자세히 다루기로 하고, deploy.wsdd 와 undeploy.wsdd 파일은 말그대로 deploy, undeploy 설정 파일이다.

 

HelloIF를 implement 한 것이 HelloSoapBindingImpl 이므로 해당 파일의 hello 메소드에 관련 로직을
작성하면 된다.


 

 

 

- STEP4. 서비스 deploy

 

 

java org.apache.axis.client.AdminClient -lhttp://localhost:8080/axis/services/AdminService deploy.wsdd

 


서비스 deploy를 완료한 후 http://localhost:8080/axis/servlet/AxisServlet에서 해당 서비스에 대한 deploy 완료 여부를 확인할 수 있다. 아니면 http://localhost:8080/axis/services/Hello?wsdl 로 확인 가능하다.

 

 

 

apache_axis.doc
0.13MB