IBM®
메인 컨텐츠로 가기
    Korea [국가변경]    이용약관
 
 
   
        제품    서비스 & 솔루션    고객지원 & 다운로드    회원 서비스    
메인 컨텐츠로 가기

한국 developerWorks  >  SOA와 웹서비스  >

웹 서비스 힌트 & 팁: JAX-RPC 대 JAX-WS, Part 3 (한글)

서비스 엔드포인트 인터페이스

developerWorks
문서 옵션

JavaScript가 필요한 문서 옵션은 디스플레이되지 않습니다.

토론

영어원문

영어원문


제안 및 의견
피드백

난이도 : 중급

Russell Butek, IT Specialist, IBM 
Nicholas Gallardo, Staff Software Engineer, IBM 

2008 년 1 월 15 일

Java™ API for XML-based RPC (JAX-RPC) 1.1과 Java API for XML Web Services (JAX-WS) 2.0을 다룬 본 시리즈에서는, Web Services Description Language (WSDL)를 서비스 엔드포인트 인터페이스(SEI)로 매핑하는 것을 비교합니다. SEI의 개념은 JAX-RPC 1.0에 처음 도입되었고, 몇 가지를 추가하여 JAX-WS 2.0에서도 유지되고 있습니다. 이 글에서는 주요한 차이점을 설명합니다.

머리말

전체적으로 보면, Java API for XML-based RPC (JAX-RPC) 1.1 서비스 엔드포인트 인터페이스(SEI)와 Java API for XML Web Services (JAX-WS) 2.0 SEI의 구조는 매우 유사하다. 이 글에서는 차이점을 설명하겠다. 구조상의 차이점은 있지만, 웹 서비스의 콘트랙트를 반영하는 인터페이스를 제공한다는 목적은 같다.

소셜 북마크

mar.gar.in mar.gar.in
digg Digg
del.icio.us del.icio.us
Slashdot Slashdot

SEI 매핑 비교

Listing 1은 간단한 HelloWorld 웹 서비스용 WSDL이다.


Listing 1. HelloWorld WSDL
                
  <?xml version="1.0" encoding="UTF-8"?>
      <wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
      xmlns:tns="urn:helloWorld/sample/ibm/com"
      xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
      xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="HelloWorld"
      targetNamespace="urn:helloWorld/sample/ibm/com">
  <wsdl:types>
    <xsd:schema targetNamespace="urn:helloWorld/sample/ibm/com"
        xmlns:tns="urn:helloWorld/sample/ibm/com"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <xsd:element name="hello">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="name" nillable="true" type="xsd:string" />
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
      <xsd:element name="helloResponse">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="response" nillable="true" type="xsd:string" />
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
    </xsd:schema>
  </wsdl:types>
  <wsdl:message name="helloRequestMsg">
    <wsdl:part element="tns:hello" name="helloParameters" />
  </wsdl:message>
  <wsdl:message name="helloResponseMsg">
    <wsdl:part element="tns:helloResponse" name="helloResult" />
  </wsdl:message>
  <wsdl:portType name="HelloWorld">
    <wsdl:operation name="hello">
      <wsdl:input message="tns:helloRequestMsg" name="helloRequest" />
      <wsdl:output message="tns:helloResponseMsg" name="helloResponse" />
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="HelloWorldBinding" type="tns:HelloWorld">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
    <wsdl:operation name="hello">
      <soap:operation soapAction="urn:helloWorld/sample/ibm/com/hello" />
      <wsdl:input name="helloRequest">
        <soap:body use="literal" />
      </wsdl:input>
      <wsdl:output name="helloResponse">
        <soap:body use="literal" />
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="HelloWorldService">
    <wsdl:port name="port" binding="tns:HelloWorldBinding">
      <soap:address location="http://tempuri.org/" />
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

Listing 2는 메소드 서명 없이 위 WSDL에서 자바 SEI의 JAX-RPC 매핑을 보여주고 있다. (나중에 자세하게 설명하겠다.)


Listing 2. JAX-RPC HelloWorld SEI
                
package com.ibm.samples;
public interface HelloWorld extends java.rmi.Remote {
...
}

Listing 3은 같은 WSDL의 JAX-WS SEI이다.


Listing 3. JAX-WS HelloWorld SEI
                
package com.ibm.samples.helloworld;

import javax.jws.WebService;

@WebService(name = "HelloWorld", targetNamespace = "urn:samples.ibm.com/HelloWorld")
public interface HelloWorld {
  ...
}

세 가지 차이점이 있다:

  • 패키지: 대상 네임스페이스가 "urn:helloWorld/sample/ibm/com"이다. 두 매핑 모두 도메인 이름과 비슷한 스트링을 취하고, 엘리먼트의 순서를 뒤집는다. JAX-RPC의 매핑은 첫 번째 슬래시에서 멈춘다. JAX-WS의 매핑은 스트링으로 이어지면서, 첫 번째 슬래시 뒤에 정보를 추가한다. 두 스팩 모두 커스텀 네임스페이스-패키지 매핑을 허용한다.

  • 주석: JAX-WS는 모든 SEI에 @WebService 주석을 포함해야 한다. 본 시리즈 Part 1에 언급했듯이, JAX-WS는 JSR-181 Web Services Metadata에 정의된 주석을 지원한다.

  • java.rmi.Remote: JAX-RPC SEI는 java.rmi.Remote 인터페이스를 확장한다. JAX-WS는 이것을 더 이상 필요로 하지 않는다.

연산 매핑에 대해 자세히 보기 전에, SEI에서 주목할 것이 있다. 비록, JAX-WS가 SEI를 갖고 있는 웹 서비스에 대한 지원을 제공하지만, 이것이 모든 서비스에 의무적인 것은 아니다. JAX-WS에서, JavaBean은 웹 서비스 구현으로서 전개될 수 있고, 이는 빈(bean)이 SEI를 반드시 포함해야 하는 JAX-RPC와는 반대된다. SEI 없이 전개된 JAX-WS 서비스는 임의의 SEI를 가진 것으로 간주된다.




위로


연산 매핑 비교하기

인터페이스를 보았으므로, 연산이 어떻게 매핑되는지를 보자. 비슷한 의미를 가진 웹 서비스를 표현하기 위해 WSDL 문서를 디자인하는 다른 방식들이 있다. 어떤 스타일의 WSDL을 사용해야 할까?에서는 다양한 스타일의 WSDL 문서에 대한 개요와 가장 적합한 것을 선택하는 방법을 설명하고 있다.

이제, JAX-RPC와 JAX-WS가 각각의 WSDL 스타일로 어떻게 매핑되는지를 살펴보자.

document/literal 래핑 패턴

Listing 1의 WSDL은 document/literal 래핑 패턴을 사용하여 포맷된다. Listing 4와 5는 JAX-RPC와 JAX-WS에서 똑 같은 래핑 연산을 위한 매핑이다. JAX-WS는 @RequestWrapper@ResponseWrapper 주석을 메소드에 추가한다. 이것은 연산 래퍼로서 작동할 엘리먼트들에 대한 추가 메타데이터와 그러한 래퍼 엘리먼트를 위해 생성되었던 자바 빈을 제공한다. 이러한 주석들은 선택적이다.


Listing 4. JAX-RPC HelloWorld SEI
                
package com.ibm.samples;

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


Listing 5. JAX-WS HelloWorld SEI
                
package com.ibm.samples.helloworld;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;

@WebService(name = "HelloWorld", targetNamespace = "urn:samples.ibm.com/HelloWorld")
public interface HelloWorld {

    @WebMethod(action = "urn:samples.ibm.com/HelloWorld/hello")
    @WebResult(name = "response", targetNamespace = "")
    @RequestWrapper(localName = "hello",
        targetNamespace = "urn:samples.ibm.com/HelloWorld", 
        className = "com.ibm.samples.helloworld.Hello")
    @ResponseWrapper(localName = "helloResponse", 
        targetNamespace = "urn:samples.ibm.com/HelloWorld", 
        className = "com.ibm.samples.helloworld.HelloResponse")
    public String hello(
        @WebParam(name = "name", targetNamespace = "")
        String name);
}

여러분도 보듯, JAX-WS 매핑은 많은 주석들을 갖고 있지만, 루트 서명으로 가면, 유일한 차이점은 JAX-RPC 메소드가 java.rmi.RemoteException을 던지지만, JAX-WS 메소드는 그렇게 하도록 설정되어 있지 않다는 점이다.

document/literal 패턴

JAX-RPC와 JAX-WS는 document/literal이지만 래핑되지 않은 매핑 연산을 지원한다. 이것을 HelloWorld 샘플에서 구현하려면, 연산 이름을 나타내는 래퍼 엘리먼트를 제거해야 한다. Listing 6은 WSDL 문서의 관련 부분들이 Listing 1의 WSDL과 비교하여 어떻게 보이는지를 보여주고 있다.


Listing 6. Document/literal WSDL
                
<wsdl:types>
  <xsd:schema targetNamespace="urn:helloWorld/sample/ibm/com"
   xmlns:tns="urn:helloWorld/sample/ibm/com"
   xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <xsd:element name="hello" type="xsd:string"/>
      <xsd:element name="helloResponse" type="xsd:string"/>
  </xsd:schema>
</wsdl:types>

<wsdl:message name="helloRequestMsg">
  <wsdl:part element="tns:hello" name="helloParameters" />
</wsdl:message>

<wsdl:message name="helloResponseMsg">
  <wsdl:part element="tns:helloResponse" name="helloResult" />
</wsdl:message>

이제, 새로운 WSDL에 대한 자바 매핑을 보자. Listing 7과 8은 각각 JAX-RPC와 JAX-WS 매핑을 보여준다. JAX-RPC 매핑이 얼마나 유사한지 알 수 있겠는가? 유일한 차이는 매개변수 이름이다. 이전 케이스와 마찬가지로, 주석을 제외하고는, JAX-RPC 매핑과 JAX-WS 매핑 사이에 실질적인 차이는 없다.


Listing 7. JAX-RPC document/literal 매핑
                
public interface HelloWorld extends java.rmi.Remote {
    public java.lang.String hello(java.lang.String helloParameters) 
        throws java.rmi.RemoteException;
}


Listing 8. JAX-WS document/literal 매핑
                
@WebService(name = "HelloWorld", targetNamespace = "urn:helloWorld/sample/ibm/com")
@SOAPBinding(parameterStyle = ParameterStyle.BARE)
public interface HelloWorld {

    @WebMethod(action = "urn:helloWorld/sample/ibm/com/hello")
    @WebResult(name = "helloResponse", 
        targetNamespace = "urn:helloWorld/sample/ibm/com", 
        partName = "helloResult")
    public String hello(
        @WebParam(name = "hello", 
            targetNamespace = "urn:helloWorld/sample/ibm/com", 
            partName = "helloParameters")
        String helloParameters);

}

JAX-WS의 경우, @RequestWrapper@ResponseWrapper 주석을 더 이상 볼 수 없다. 또한, 새로운 주석, @SOAPBinding이 인터페이스 레벨에 나타난다. 이 주석은 매개변수 스타일에 대한 정보를 제공한다. 이것이 없을 경우, parameterStyle 애트리뷰트에 대한 기본 값은 래핑되는데, 이것은 Listing 1의 WSDL과 같다.

RPC/literal 패턴

다음 예제는 이전 두 개와 다소 다르다. RPC/literal 스타일 WSDL에서, 파트(part)는 엘리먼트 보다는 유형의 관점에서 정의된다. Listing 9에는 이와 관련된 WSDL 차이점들이 포함되어 있다.


Listing 9. RPC/literal WSDL 변화
                
<wsdl:types/>

<wsdl:message name="helloRequestMsg">
  <wsdl:part name="helloParameters" type="xsd:string"/>
</wsdl:message>

<wsdl:message name="helloResponseMsg">
  <wsdl:part name="helloResult" type="xsd:string"/>
</wsdl:message>

Listing 10과 11의 자바 매핑은 WSDL에서의 변화를 반영하고 있다. 주석만 제거되면 동일한 매핑임을 알 수 있다.


Listing 10. JAX-RPC RPC/literal 매핑
                
public interface HelloWorld extends java.rmi.Remote {
    public java.lang.String hello(java.lang.String helloParameters)
        throws java.rmi.RemoteException;
}


Listing 11. JAX-WS RPC/Literal 매핑
                
@WebService(name = "HelloWorld", targetNamespace = "urn:helloWorld/sample/ibm/com")
@SOAPBinding(style = Style.RPC)
public interface HelloWorld {

    @WebMethod(action = "urn:helloWorld/sample/ibm/com/hello")
    @WebResult(name = "helloResult", partName = "helloResult")
    public String hello(
        @WebParam(name = "helloParameters", partName = "helloParameters")
        String helloParameters);

}

JAX-WS 인터페이스를 이전 것과 비교하면, @SOAPBinding 주석이 남아있지만, 이제는 매개변수 스타일에는 사용되지 않고, 오히려 WSDL 스타일에 사용된다는 것을 알 수 있다.

RPC/encoded 패턴

RPC/encoded 스타일 연산에 대해서는 비교할 것이 없다. JAX-WS는 데이터를 위해 인코딩 된 표현을 포함하고 있는 WSDL 문서용 매핑을 지원하지 않는다. 이것은 WS-I의 Basic Profile 1.1에 순응하는 JAX-WS에서 기인한 것으로, 인코딩 된 WSDL 문서의 사용을 허용하지 않는다. RPC/encoded 웹 서비스를 구현하는 좋은 이유가 있는데, JAX-RPC 매핑을 고수해야 하는 경우에도, 상호 운용성 있는 웹 서비스를 작성해야 한다면, RPC/encoded를 사용해서는 안된다.




위로


기타 차이점들

JAX-WS와 JAX-RPC의 연산 매핑의 주요한 차이점은 비동기식 연산의 도입이다. 투웨이(two-way) 메시지 흐름을 가진 WSDL 연산 또는 클라이언트가 응답을 받아야 하는 쪽은 비동기식 자바 표현으로 매핑될 수 있다. 두 개의 다른 메커니즘, 비동기식 콜백과 비동기식 폴링이 있는데, 이는 두 개의 다른 매핑을 필요로 한다. 다음 글에서는 이러한 두 개의 연산 유형이 어떻게 작동하는지를 설명하겠다. 이 글에서는 예제만 설명하겠다. Listing 12에는 비동기식 콜백 연산이 포함되어 있는데, 여기에서, javax.xml.ws.AsyncHandler 객체가 콜백 객체이다. Listing 13에는 비동기식 폴링 연산 매핑이 포함되어 있다.


Listing 12. JAX-WS 비동기식 콜백
                
@WebMethod(action = "urn:samples.ibm.com/HelloWorld/hello")
@RequestWrapper(localName = "hello",
    targetNamespace = "urn:samples.ibm.com/HelloWorld", 
    className = "com.ibm.samples.helloworld.Hello")
@ResponseWrapper(localName = "helloResponse", 
    targetNamespace = "urn:samples.ibm.com/HelloWorld", 
    className = "com.ibm.samples.helloworld.HelloResponse")
public Future<?> helloAsync(
    @WebParam(name = "name", targetNamespace = "")
    String name,
    @WebParam(name = "asyncHandler", targetNamespace = "")
    AsyncHandler<String> asyncHandler);
 


Listing 13. JAX-WS 비동기식 폴링
                
@WebMethod(action = "urn:samples.ibm.com/HelloWorld/hello")
@RequestWrapper(localName = "hello", 
    targetNamespace = "urn:samples.ibm.com/HelloWorld", 
    className = "com.ibm.samples.helloworld.Hello")
@ResponseWrapper(localName = "helloResponse", 
    targetNamespace = "urn:samples.ibm.com/HelloWorld", 
    className = "com.ibm.samples.helloworld.HelloResponse")
public Response<String> helloAsync(
    @WebParam(name = "name", targetNamespace = "")
    String name);

JAX-RPC에 WSDL 연산을 위한 어떤 비동기식 매핑이 없기 때문에, 여기에서는 비교할 것이 아무것도 없다. 하지만, 중요한 것은 비동기식 매핑이 클라이언트 측에만 적용된다는 점이다. 어떤 비동기식 매핑도 서비스 엔드포인트를 위해서는 존재하지 않으며, 오직 클라이언트를 위해서만 존재한다.

IN/OUT 매개변수 비교하기

JAX-RPC와 JAX-WS는 IN/OUT 매개변수로 알려진 매개변수들을 지원한다. Listing 13에서, Listing 1의 WSDL에 추가된 IN/OUT 매개변수를 볼 수 있다. "inout" 이라는 이름을 가진 매개변수가 인풋과 아웃풋에 나타난다. 이 시나리오에서, JAX-RPC와 JAX-WS는 그 매개변수를 홀더 매개변수로 매핑하지만, 이것의 결과는 각 매핑마다 다르다.


Listing 14. IN/OUT 매개변수를 가진 WSDL
                
<xsd:element name="hello">
  <xsd:complexType>
    <xsd:sequence>
      <xsd:element name="name" nillable="true" type="xsd:string" />
      <xsd:element name="inout" nillable="true" type="xsd:string" />
    </xsd:sequence>
  </xsd:complexType>
</xsd:element>

<xsd:element name="helloResponse">
  <xsd:complexType>
    <xsd:sequence>
      <xsd:element name="response" nillable="true" type="xsd:string" />
      <xsd:element name="inout" nillable="true" type="xsd:string" />
    </xsd:sequence>
  </xsd:complexType>
</xsd:element>

Listing 15는 홀더 매개변수에 대한 JAX-RPC 매핑이고, Listing 16은 JAX-WS 매핑이다.


Listing 15. IN/OUT 매개변수를 가진 JAX-RPC SEI
                
public interface HelloWorld extends java.rmi.Remote {
    public java.lang.String hello(
        java.lang.String name, 
        javax.xml.rpc.holders.StringHolder inout) throws java.rmi.RemoteException;
}


Listing 16. IN/OUT 매개변수를 가진 JAX-WS SEI
                
@WebService(name = "HelloWorld", targetNamespace = "urn:helloWorld/sample/ibm/com")
public interface HelloWorld {

    @WebMethod(action = "urn:helloWorld/sample/ibm/com/hello")
    @RequestWrapper(localName = "hello", 
        targetNamespace = "urn:helloWorld/sample/ibm/com", 
        className = "helloworld.sample.ibm.com.Hello")
    @ResponseWrapper(localName = "helloResponse", 
        targetNamespace = "urn:helloWorld/sample/ibm/com", 
        className = "helloworld.sample.ibm.com.HelloResponse")
    public void hello(
        @WebParam(name = "name", targetNamespace = "")
        String name,
        @WebParam(name = "inout", targetNamespace = "", mode = Mode.INOUT)
        Holder<String> inout,
        @WebParam(name = "response", targetNamespace = "", mode = Mode.OUT)
        Holder<String> response);

}

JAX-RPC의 경우, 알려진 유형에 대한 홀더 클래스로서 스팩에 의해 정의된 클래스 세트가 있다. 여기에는 java.lang.String 같은 유형과 기타 기본 유형들이 포함된다. 사용자 정의 유형의 경우, JAX-RPC는 커스텀 홀더 클래스가 사용자 정의 유형을 핸들하기 위해 생성되어야 한다. 한편, JAX-WS는 Java 5의 Generics 기능을 사용하여 사용자 정의 유형을 포함하여 모든 유형에 맞는 하나의 클래스를 제공한다.

여기에서 기억해야 할 것은 리턴 유형에서의 차이점이다. 리턴 유형을 JAX-RPC가 하는 것처럼 유지하기 보다는, JAX-WS는 메소드를 유효한 것으로 하고, 리턴 값이었던 것에 대한 홀더를 활용한다. JAX-WS의 규칙에 의해서, 한 연산에 대해 OUT 매개변수로 간주될 수 있는 한 개 이상의 매개변수가 있을 대, 리턴 유형은 유효한 것이 되고, 모든 OUT 매개변수들은 홀더 유형으로 매핑된다.




위로


요약

위 예제에서는, JAX-RPC와 JAX-WS간 많은 차이점이 있지만, WSDL에서 서비스 엔드포인트 인터페이스로의 매핑은 매우 유사하다는 것을 증명했다. 주요한 차이점은 다음과 같다:

  • 패키지 이름이 다르다.

  • JAX-RPC는 java.rmi.Remote와 java.rmi.RemoteException을 필요로 하는데, JAX-WS는 그렇지 않다.

  • 홀더는 다르게 정의된다.

많은 유사점들이 있지만, 한 가지 주요한 차이가 JAX-WS SEI를 JAX-RPC SEI와는 완전히 다른 것으로 만든다. JSR-181 주석을 사용하면, JAX-WS SEI에게 자바 중심적인 웹 서비스 뷰를 나타낼 뿐만 아니라, WSDL 중심의 뷰를 표현할 수 있는 기능이 부여된다. 많은 주석들은 자바 정보를 WSDL 구조에 매핑하는데 사용된다. 이 정보는 JAX-RPC SEI의 어떤 폼에도 존재하지 않는다. JAX-WS에만 있는 것에는 비동기식 호출 모델과, 처음부터 생성된 SEI를 요구하지 않는다는 사실이다. 반면, JAX-RPC는 JAX-WS가 갖고 있지 않은 것을 갖고 있다. RPC/encoded WSDL을 지원한다.



참고자료

교육

제품 및 기술 얻기

토론


필자소개

Russell Butek은 IBM SOA와 웹 서비스 컨설턴트이다. IBM WebSphere 웹 서비스 엔진 개발자를 역임했다. JAX-RPC Java Specification Request (JSR) 전문가 그룹의 멤버로도 활동했다. AXIS 1.0을 JAX-RPC에 순응시키는 Apache의 AXIS SOAP 엔진 구현에 참여했다.


Nick Gallardo는 IBM 소프트웨어 엔지니어이다. 웹 서비스의 다양한 측면들을 연구하고 있다. 최근에는 JAX-WS 지원도 하고 있다. 이전에는, WebSphere와 Tivoli 플랫폼에서 작업했다.




기사에 대한 평가


보다 나은 서비스를 제공하기 위함이오니 잠시 짬을 내어 이 양식을 제출하여 주십시오.



아니오잘 모르겠음
 


 


12345
 



위로


IBM is a trademark of IBM Corporation in the United States, other countries, or both. Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both. Other company, product, or service names may be trademarks or service marks of others. 기타 회사, 제품, 및 서비스명은 다른 상표나 서비스 마크일 수 있습니다.

developerWorks 콘텐트를 다른 사이트에 전재하기:
developerWorks 콘텐트에 대한 저작권은 IBM에 있습니다. IBM의 서면 허가나 원본 저자의 허락이 없이는 전재를 금합니다. 저희 콘텐트를 전재하시려면 IBM developerWorks 담당자 에게 문의하십시오.
    IBM 소개 개인정보 보호정책 문의