2008년 3월 4일 화요일

Apache Axis2 User's Guide -Building Services

이제 당신은 WSDL을 이용해 클라이언트를 생성하기위해 Axis2를 사용하는 방법을 알고 있다, 이번 섹션에서는 좀더 깊이 들어갈 것이다, 서비스를 생성하는 방법과 아무것도 없는 상태에서 서버스와 클라이언트 둘다를 생성하는 방법을 보여줄 것이다.



Content

-------------------------------------------------------------------------------------------------------------------
    ● Introducing Axis2

        ○ What is Axis2?
        ○ What's under the hood?
        ○ How Axis2 handles SOAP messages
        ○ Axis2 distributions
        ○ The Axis2 Standard Binary Distribution
        ○ Axis2.war Directory hierarchy
        ○ Axis2 Documents Distribution
        ○ Axis2 and clients


    ● Installing and testing client code


    ● Introduction to Services

        ○ Message Exchange Patterns


    ● Creating Clients

        ○ Choosing a Client Generation Method
        ○ Generating Clients
        ○ Axis Data Binding (ADB)


    ● Building Services

        ○ Getting Comfortable with Available Options
        ○ Creating a service from scratch
        ○ Deploying Plain Old Java Objects
        ○ Deploying and running an Axis2 service created from WSDL


    ● Samples


    ● For Further Study



Getting Comfortable with Available Options

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

아래와 같이 Axis2는 서비스를 생성하는 몇가지 방법을 제공한다:


    ● 아무것도 없는상태에서 서버스를 생성하고 빌드한다: 이 경우에 당신은 AXIOM OMElement 객체들에 구체적으로 접근하기

        위한 서비스 클래스를 빌드한 다음 services.xml 파일을 생성하고 디플로이 하기위해 이것을 묶는다.


    ● Plain Old Java Objects (POJOs)를 서비스로 디플로이한다.


    ● WSDL로 부터 서비스를 생성한다: WSDL만 가지고 클라이언트를 생성 할 수 있다. 당신은 서비스의 skeleton을

        생성 할 수 있다.


이 3개의 옵션들을 살펴보자.



Creating a Service From Scratch

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

아무것도 없는상태에서 서버스를 생성하는 것은 가장 편리한 방법이 아니지만 가장 많은 제어권을 당신에게 준다. 이 과정은 몇단계를 거쳐야한다.


The short story:


    1. org.apache.axiom.om.OMElement 객체를 알규먼트로 받는 함수에의해 대표되는 각각의 오퍼레이션을 가지고 있는

       서비스 클래스를 생성한다. (OMElement는 AXIs2 Object Model (AXIOM) 이 XML element를 표현하기위한 것이다.)


    2. 서비스 디스크립터(services.xml)를 생성한다. 이것은 서비스에 의해 사용되는 클래스와 적절한 메세지 receiver들을

       정의한다.


    3. .aar 파일을 생성한다. 이 파일은 패키지를 기준으로 적절한 위치에 있는 클래스들과 META-INF 디렉토리안에 있는

       services.xml 파일을 포함하고 있다.


    4. 웹 관리자 어플리케이션을 이용하거나 Axis2 서비스 디렉토리에 .aar 파일을 복사해 넣는 방식으로 .aar 파일을

       디플로이한다.

The long story:


먼저 서비스 클래스를 생성한다. 서비스 클래스는 Axis2 라이버러리 안에 있는 클래스를 이용하는 plain Java class 이다(참조 Code Listing 8).


Code Listing 8-Creating the Service Class

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


------------------------------------------------------------------------------------------------------------
package org.apache.axis2.axis2userguide;


import javax.xml.stream.XMLStreamException;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;


public class SampleService {


    public OMElement sayHello(OMElement element) throws XMLStreamException {
            element.build();
            element.detach();

            String rootName = element.getLocalName();
            System.out.println("Reading "+rootName+" element");
           
            OMElement childElement = element.getFirstElement();
            String personToGreet = childElement.getText();

            OMFactory fac = OMAbstractFactory.getOMFactory();
            OMNamespace omNs = fac.createOMNamespace("
http://example1.org/example1", "example1");
            OMElement method = fac.createOMElement("sayHelloResponse", omNs);
            OMElement value = fac.createOMElement("greeting", omNs);
            value.addChild(fac.createOMText(value, "Hello, "+personToGreet));
            method.addChild(value);

            return method;
     }

private void ping(){
     }


}

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


소스를 컴파일할때 당신의 클래스패스에 Axis2 라이버러리들이 포함되 있는지 확인하라.


Axis2는 AXIOM (또는 AXIs Object Model) 를 이용한다. 이것은 StAX API (Streaming API for XML) 에 기반을둔 구조와 비슷한 DOM (Document Object Model) 이다.

서비스 처럼 동작하는 함수들은 그들의 알규먼트로 OMElement를 가지고 있어야 한다. OMElement는 들어오는 SOAP 메세지의 payload를 표현한다. (OMElement는 DOM Element 객체처럼 단지 AXIOM이 XML element를 표현하는 방식이다.)

이 경우, 당신은 payload element의 첫번째 child의 컨텐츠를 추출한다음 텍스트를 이것에 추가한다. 그리고 이것을 리턴되는 OMElement의 컨텐츠로 사용한다.

이것이 "in only" 서비스가 아니라면, 이 함수들은 OMElement를 리턴 해야한다. 리턴되는 SOAP 메세지의 payload가 되기 때문이다.


서비스에 이 클래스를 넣기위해 Code Listing 9에 있는 서비스 디스크립션 파일(services.xml)을 생성하라.

Code Listing 9 - Create the Service Description
--------------------------------------------------------------------------------------------------------------------


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

<service name="UserGuideSampleService">
    <description>
        This is a sample service created in the Axis2 User's Guide
    </description>

    <parameter name="ServiceClass" locked="false">

        org.apache.axis2.axis2userguide.SampleService
    </parameter>

    <operation name="sayHello">
        <messageReceiver class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
    </operation>
    <operation name="ping">
        <messageReceiver class="org.apache.axis2.receivers.RawXMLINOnlyMessageReceiver"/>
    </operation>
</service>

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


이 문서는 Web Administration Application이 호출하는 service와 request들을 처리하는데 사용되는 클래스를 정의한다. 각각의 오퍼레이션을 위해 적절한 message receiver class를 정의한다.


클래스의 메인 디렉토리에 새로운 META-INF 디렉토리를 생성하라. (이 경우, org 디렉토리를 포함하고 있는 디렉토리와 동일한 디렉토리이다.) 그런다음 services.xml 파일을 그곳에 두라.


jar cvf SampleService.aar ./* 명령을 이용해 .aar 파일을 생성하라.


Web Administration application을 이용하거나 SampleService.aar 파일을 Axis2 services 디렉토리에 복사해 넣는 방식을 이용해 SampleService.aar 파일을 디플로이 하라.


이제 당신은 서비스에 직접 접근 할 수 있는 클라이언트 클래스를 생성 할 수 있다 (참조 Code Listing 10).

Code Listing 10 - Create a Client Class that Accesses the Service Directly

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


------------------------------------------------------------------------------------------------------------
package org.apache.axis2.axis2userguide;


import javax.xml.stream.XMLStreamException;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.Constants;
import org.apache.axis2.client.ServiceClient;


public class SampleClient {

        private static EndpointReference targetEPR =

                                 new EndpointReference("http://localhost:8080/axis2/services/UserGuideSampleService");

       

    public static OMElement greetUserPayload(String personToGreet) {
        OMFactory fac = OMAbstractFactory.getOMFactory();
        OMNamespace omNs = fac.createOMNamespace("http://example1.org/example1", "example1");
        OMElement method = fac.createOMElement("sayHello", omNs);
        OMElement value = fac.createOMElement("personToGreet", omNs);
        value.addChild(fac.createOMText(value, personToGreet));
        method.addChild(value);
        return method;
    }

public static void main(String[] args) {
        try {
            OMElement payload = SampleClient.greetUserPayload("John");
            Options options = new Options();
            options.setTo(targetEPR);
           
            options.setTransportInProtocol(Constants.TRANSPORT_HTTP);

            ServiceClient sender = new ServiceClient();
            sender.setOptions(options);
            OMElement result = sender.sendReceive(payload);

            String response = result.getFirstElement().getText();
            System.out.println(response);

        } catch (Exception e) {    //(XMLStreamException e) {
            System.out.println(e.toString());
        }
    }

   
}

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


이 클래스는 OMElement를 보내고 받는 동일한 기술을 사용한다. 그러나 Options 클래스를 사용하는부분을 아는것이 중요하다.

이 클래스는 리턴되는 메세지를 위해 사용되는 transport와 사용하기 위한 SOAP 버젼과 같은 속성들을 결정하는 것을 가능하게 한다. 보내는 메세지에 사용되는 transport는 지정된 URL로 부터 추즉 가능하다.

클라이언트가 서버스와 상호작용하는 방식에 영향을 주는 특정 속성들의 setter와 getter 함수를 제공하는것 뿐만 아니라, Options 클래스는 당신이 Options 객체들 사이에 상속관계를 생성하는것을 가능하게 한다. 그래서, 만약 현재 사용되는 Options 객체에 속성이 없으면 클라이언트는 현재 Options 객체의 부모 Options 객체를 검사 할 수 있다.


위의 SampleClient.java를 컴파일하고 실행하라. 모든 axis2 라이버러리들이 당신의 클래스 패스에 있는지 확인하라. 만약 모든것이 정상이라면 콘솔창에 'Hello, John' 이 나타날 것이다.

Deploying Plain Old Java Objects (POJOs)

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


웹 서비스를 생성하는 매우 쉬운 방법중의 하나는 간단히 서비스에 상응하는 자바 객체를 디플로이 하는 것이다. Code Listing 11 에서 보이는 클래스 부터 시작하자.



Code Listing 11 - Creating the Class SampleService

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


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

package org.apache.axis2.axis2userguide;


public class SampleService {


    public void doInOnly(){
        return;
    }
    
    public String noParameters(){
        return "Hello";
    }
   
    public String twoWayOneParameterEcho(String toEcho){
        return toEcho;
    }
   
    public boolean multipleParametersAdd(float price, int itemId, String description, String itemName){
        //Code to handle the logic
        return true;
    }
 
}

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

다음은 어떤 웹 서비스에 어떤 클래스가 대응하는지 Axis2에게 알려줘야 할 필요가 있다. services.xml 파일을 생성하고 Code Listing 12 의 내용을 추가함으로써 이 일이 가능하다.



Code Listing 12 - Creating services.xml

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


------------------------------------------------------------------------------------------------------------
<service name="SampleService" scope="application">
    <description>
        Sample Service
    </description>
    <messageReceivers>
        <messageReceiver
            mep="
http://www.w3.org/2004/08/wsdl/in-only"

            class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>
        <messageReceiver
            mep="
http://www.w3.org/2004/08/wsdl/in-out"
            class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
    </messageReceivers>
    <parameter name="ServiceClass">
        org.apache.axis2.axis2userguide.SampleService
    </parameter>
</service>

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

이 파일은 InOnly와 InOut MEPs(message exchange patterns) 를 service에서 가능하게 만들고 어떤 클래스를 호출해야 하는지 Axis2에 알려준다; operation들은 함수이름들과 매치가 되어야만 한다. 다르게 말하면, Axis2는 자동으로 multipleParametersAdd operation 호출을 org.apache.axis2.axis2userguide.SampleService.multipleParametersAdd() 함수로 보낸다.


이제 distribution을 생성할 시간이다. 아래의 디렉토리 구조안에 당신의 파일들을 배치하라. (참조 Code Listing 13)



Code Listing 13- Create the Directory Structure for the Distribution

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


------------------------------------------------------------------------------------------------------------
 - SampleService
   - META-INF
     - services.xml
   - org
     - apache
       - axis2
         - axis2userguide
           - SampleService.class

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


마지막으로, SampleService 디렉토리를 서블릿 엔진의 webapps/axis2/WEB-INF/services 디렉토리에 복사해 넣음으로서 서비스를 디플로이 하라. http://<host>:<port>/axis2/services/listServices 페이지를 검사해 올바르게 디플로이 됬는지 확인할수 있다.

Deploying and Running an Axis2 Service Created from WSDL

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


If you have a WSDL file, you can easily create and deploy a service based on that description. For example, to create a service based on the same WSDL file used in the clients section of this document, you'd employ the following steps.


만약 당신이 WSDL 파일을 가지고 있으면 그 description을 기준으로 쉽게 서비스를 생성하고 디플로이 할 수 있다. 예를 들어,


The short story:


    1. Axis2 standard distribution이 없다면 다운로드 하라.


    2. WSDL2Java 유틸리티를 이용해 skeleton을 생성하라:


        java org.apache.axis2.wsdl.WSDL2Java -uri file:///C:/apps/axis2/samples/zSample/Axis2UserGuide.wsdl

        -p org.apache.axis2.axis2userguide -d adb -s -wv 1.1 -ss -sd -ssi


    3. *Skeleton.java 파일을 열어 생성된 함수들 안에 당신의 서비스 기능을 추가하라.


    4. ant jar.server 명령을 실행해 서비스를 빌드하라.


    5. build/lib/*.aar 파일을 <J2EE_HOME>/webapps/axis2/WEB-INF/services 폴더에 복사해 넣어 서비스를 디플로이 하라.


    6. http://<server>:<port>/axis2/services/listServices 페이지를 열어 서비스가 올바르게 디플로이 됬는지 확인하라.
 

The long story:


클라이언트를 생성하는 경우처럼 Axis2 Standard Distribution이 필요하다. Axis2 War Distribution에는 WSDL2Java 유틸리티가 없기 때문이다. 이것을 다운로드하고 압축을 푼다음 AXIS2_HOME 환경변수에 압축을 푼 폴더의 경로를 셋팅하라.


이제 당신은 실제 서비스를 생성할 준비가 됬다. 클라이언트를 생성할때 참조했던 WSDL 파일을 사용할 것이다. 이 파일에는 4개의 오퍼레이션(NoParameters, TwoWayOneParameterEcho, MultipleParametersAddItem, DoInOnly)이 있다. Code Listing 14 에서 처럼 WSDL2Java 유틸리티를 사용해 서비스를 생성하라.

Code Listing 14 - Using the WSDL2Java Utility to Generate the Service

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


java org.apache.axis2.wsdl.WSDL2Java -uri
file:///C:/apps/axis2/samples/zSample/Axis2UserGuide.wsdl -p
org.apache.axis2.axis2userguide -o target_directory_name -d adb -s -wv 1.1 -ss -sd


이 명령문은 유틸리티에게 당신이 생성하기 원하는 Axis2UserGuide.wsdl 안에 있는 오퍼레이션의 서비스를 알려준다. 그리고 생성된 자바 클래스들은 org.apache.axis2.axis2userguide 패키지 안에 놓여질 것이다 (-p). (당신은 적절한 디렉토리들을 볼수 있다. code listing 14 에 지정된 "target_directory_name" 디렉토리 안에 깔끔하게 정리된 이 디렉토리들이 생성될 것이다. 만약 이 디렉토리가 존재하지 않으면 생성될 것이다.) 이것은 또한 Axis2 DataBinding Framework(ADB)을 사용하라고 가리킨다 (-d). synchronous(blocking) 코드를 생성하고 (-s), 클라이언트에 대응하는 server-side 코드를 생성하고 (-ss). services.xml service descriptor 파일을 포함하라고 가리킨다 (-sd). 이것은 또한 WSDL 파일의 버젼을 1.1로 명세한다 (-wv).


이제, 당신이 선택한 디렉토리안에 3개의 새로운 아이템들이 보일 것이다: build.xml은 Ant를 위한 지시들을 포함하고있다. src 디렉토리는 모든 생성된 클래스들과 stub들을 포함하고 있다. resources 디렉토리는 다시 생성된 버젼의 WSDL 파일을 포함한다. services.xml 파일은 궁극적으로 서비스의 행동을 제어한다.


이제 당신은 서비스를 컴파일 할 수 있다, 그러나 실제로 아직까지 아무일도 하지 않았다. 당신은 src\org\apache\axis2\axis2userguide\Axis2UserGuideServiceSkeleton.java 파일을 열어 굵은 글씨의 코드를 수정해 그 문제를 해결 할 수 있다. -- 파라미터 갯수를 관리하는것을 확실히 하라 -- 또는 아래의 Code Listing 15 의 모든 코드를 교체할 수 있다.



Code Listing 15 - Compiling the Service

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


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

/**
 * Axis2UserGuideServiceSkeleton.java
 *
 * This file was auto-generated from WSDL
 * by the Apache Axis2 version: SNAPSHOT Oct 15, 2006 (11:23:18 GMT+00:00)
 */
package org.apache.axis2.axis2userguide;

/**
 *  Axis2UserGuideServiceSkeleton java skeleton for the axisService
 */

public class Axis2UserGuideServiceSkeleton {
         
    /**
     * Auto generated method signature
     * @param param7
    */
    public  org.apache.axis2.axis2userguide.NoParametersResponse NoParameters
                                    (org.apache.axis2.axis2userguide.NoParametersRequest param7)        
  {
        System.out.println(param7);

        NoParametersResponse res = new NoParametersResponse();

        return res;
    }
         
    /**
     * Auto generated method signature
     * @param param9
    */
    public org.apache.axis2.axis2userguide.TwoWayOneParameterEchoResponse TwoWayOneParameterEcho
                                                 (org.apache.axis2.axis2userguide.TwoWayOneParameterEchoRequest param9)
    {
        System.out.println(param9.getEchoString());

        TwoWayOneParameterEchoResponse res = new TwoWayOneParameterEchoResponse();
        res.setEchoString(param9.getEchoString());

        return res;
    }
         
    /**
     * Auto generated method signature
     * @param param11
    */
    public void DoInOnly (org.apache.axis2.axis2userguide.DoInOnlyRequest param11)        
    {
        System.out.println(param11.getMessageString());
    }
         
    /**
     * Auto generated method signature
     * @param param12
    */

 
public org.apache.axis2.axis2userguide.MultipleParametersAddItemResponse MultipleParametersAddItem
                                                 (org.apache.axis2.axis2userguide.MultipleParametersAddItemRequest param12)
    {
        System.out.println(param12.getPrice());
        System.out.println(param12.getItemId());
        System.out.println(param12.getDescription());
        System.out.println(param12.getItemName());

        MultipleParametersAddItemResponse res = new MultipleParametersAddItemResponse();
       
        res.setSuccessfulAdd(true);
        res.setItemId(param12.getItemId());

        return res;
    }
    
}

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

클라이언트를 생성하는 경우와 마찬가지로 모든 클래스들(MultipleParametersAddItemRequest와 TwoWayOneParameterEchoResponse 같은)은 유틸리티에 의해 생성된다. 그리고 skeleton 파일과 동일한 디렉토리 안에서 찾을수 있다. 그들은 response안의 엘리먼트의 컨텐츠의 값을 셋팅하는 setSuccessfulAdd()와  response안의 엘리먼트의 컨텐츠를 찾는 getItemName() 같은 함수를 포함하고 있다.

ant jar.server 명령문으로 파일을 저장하고 컴파일 하라.


모든 것이 잘 되면, 명령창에서 BUILD SUCCESSFUL 메세지를 볼 것이다. 그리고 새로 생성된 build/lib 디렉토리안에 Axis2UserGuideService.aar 파일을 볼수 있다.

사용자 삽입 이미지

이제 당신은 서비스를 서버에 디플로이 해야 한다. 이를 위해서는 Axis2UserGuideService.aar 파일을 어플리케이션 서버의 WEB-INF/services 디렉토리에 복사해 넣어라. (또한 당신은 관리 툴을 사용하기 위한 옵션도 가지고 있다. 더 많은 정보를 원하면 Web Administrator's Guide를 보라.)


그 서비스가 올바르게 디플로이 됬는지 확인하기 위해 http://<host>:<port>/axis2/services/listServices 페이지의 서비스 리스트를 확인하라.

사용자 삽입 이미지

이제 당신은 Generating Clients 문서에서 빌드한 클라이언트들 중 하나를 이용해 서비스에 접근할 수 있다.


 

댓글 없음:

댓글 쓰기