제25장 JAX-RPC 웹 서비스 설정 파일 작성

본 장에서는 JAX-RPC 웹 서비스의 표준 웹 서비스 DD 파일 작성 방법과 JAX-RPC 매핑 파일 작성 방법에 대해 설명한다.

25.1. JAX-RPC 웹 서비스 DD 파일 작성

Jakarta EE JAX-RPC 웹 서비스는 webservices.xml이라는 이름을 가진 웹 서비스 서술자를 Java 클래스 Endpoint나 EJB Endpoint를 포함하는 압축 파일(WAR나 JAR)에 포함할 것을 요구한다.

webservices.xml을 EJB Endpoint의 경우에는 EJB JAR 파일의 META-INF 디렉터리에 저장하고, 서블릿 Endpoint의 경우에는 WAR 파일의 WEB-INF 디렉터리에 위치시킨다.

다음은 FileAttachmentService라는 웹 서비스의 webservices.xml 파일이다.

[예 25.1] JAX-RPC 웹 서비스 : <webservices.xml>

<?xml version="1.0"?>
<webservices version="1.1" xmlns="http://java.sun.com/xml/ns/j2ee">
    <webservice-description>
        <webservice-description-name>
            FileAttachmentService
        </webservice-description-name>
        <wsdl-file>
            WEB-INF/wsdl/FileAttachmentService.wsdl
        </wsdl-file>
        <jaxrpc-mapping-file>
            WEB-INF/FileAttachmentService-mapping.xml
        </jaxrpc-mapping-file>
        <port-component>
            <port-component-name>FileAttPort</port-component-name>
            <wsdl-port xmlns:ns2="urn:FileAttachmentService">
                ns2:FileTransferIFPort
            </wsdl-port>
            <service-endpoint-interface>
                filetransfer.FileTransferIF
            </service-endpoint-interface>
            <service-impl-bean>
                <servlet-link>FileAttachmentServlet</servlet-link>
            </service-impl-bean>
            <handler>
                <handler-name>ServerAttachmentHandler</handler-name>
                <handler-class>
                    filetransfer.ServerAttachmentHandler
                </handler-class>
                <init-param>
                    <param-name>directory</param-name>
                    <param-value>/temp</param-value>
                </init-param>
            </handler>
        </port-component>
    </webservice-description>
</webservices>


webservices.xml 파일의 root element는 <webservices>이고, <webservice-description>을 하나 또는 그 이상을 필수 요소로 가진다.

<webservice-description>은 동일한 WSDL을 사용하는 Java 클래스나 EJB Endpoint의 집합을 서술한다. 즉, 패키징 내의 다른 WSDL 각각의 파일 들에 대해서 <webservice-description>이 하나씩 존재해야 한다. 예를 들면 2개의 다른 Java 클래스 Endpoint가 각각 WSDL을 별도로 가지고 하나의 WAR 파일 안에 존재한다면 각각의 JSE를 서술하기 위해서 <webservice-description>은 2개가 존재해야 한다.

<webservice-description>는 Jakarta EE Endpoint를 WSDL 포트 정의, DD 구현, JAX-RPC 매핑 파일 그리고 Endpoint 인터페이스로 바인딩시켜주는 역할을 하며, 본 장에서는 이들의 관계와 필요성에 대해서 설명한다.

25.2. 웹 서비스의 매핑 파일 작성

JAX-RPC 매핑 파일은 JEUS 웹 서비스에 내장된 JAX-RPC 컴파일러가 WSDL 문서와 웹 서비스 Endpoint를 나타내는 Java 인터페이스의 관계를 이해하는 것을 도와준다. 많은 경우에 WSDL과 Java의 매핑은 매핑 파일이 없어도 큰 문제가 없지만 명시적인 정의가 필요할 때가 있으며, 그러한 필요에 의해서 JAX-RPC 매핑 파일이 도입되었다.

JAX-RPC 매핑 파일은 Jakarta EE 웹 서비스 Endpoint나 Jakarta EE 웹 서비스 클라이언트를 사용할 때마다 필요하며, WSDL 문서와 JAX-RPC 매핑 파일은 1대 1로 대응한다. 즉, 각각의 WSDL 파일에는 하나씩의 JAX-RPC 매핑 파일이 존재한다.

25.2.1. JAX-RPC 매핑 파일 내용

JAX-RPC 매핑 파일은 다음과 같은 관계에 있는 요소들의 매핑을 정의한다.

  • XML 복합 타입(Complex Type)과 Java Bean

  • Fault 메시지와 예외 클래스

  • WSDL의 portType 정의와 SEI(Service Endpoint Interface)

  • WSDL의 서비스 정의와 서비스 인터페이스

JAX-RPC 매핑 파일에 정의되지 않은 것들은 WSDL과 XML의 Java로의 표준 매핑 법칙을 따라서 매핑된다. 그리고 매핑 파일에서 정의 되는 것들은 항상 표준 매핑 법칙에 우선한다.

25.2.2. JAX-RPC 매핑 파일 작성

매핑 파일은 상당히 내용이 복잡해 보이고, 크기에 있어서도 단일 설정 파일 중에 큰 편이다.

전체적인 설정 파일의 구성은 다음과 같다.

[예 25.7] JAX-RPC 매핑 파일의 구조

<java-wsdl-mapping>
    <package-mapping/>
    <java-xml-type-mapping/>
    <exception-mapping/>
    <service-interface-mapping/>
    <service-endpoint-interface-mapping>
        <service-endpoint-method-mapping/>
        <service-endpoint-method-mapping/>
        . . .
    </service-endpoint-interface-mapping>
    <service-interface-mapping/>
    <service-endpoint-interface-mapping>
        <service-endpoint-method-mapping/>
        <service-endpoint-method-mapping/>
        . . .
    </service-endpoint-interface-mapping>
</java-wsdl-mapping>


  • <java-wsdl-mapping>

    JAX-RPC 매핑 파일의 최상위 element이며, 다른 매핑 element들을 포함하고 있다.

  • <package-mapping>

    JAX-RPC 컴파일러가 WSDL에 정의된 여러 가지 타입에 대해 Java 클래스와 인터페이스 정의를 생성하려고 할 경우 사용된하는 항목으로 반드시 설정되어야 한다.

    <package-type>의 값은 Java 패키지의 이름이며, <namespaceURI>의 값은 지정된 Java 패키지로 매핑되어야 하는 XML 이름 공간이다.

    <java-wsdl-mapping version="1.1"
        xmlns="http://java.sun.com/xml/ns/j2ee">
        <package-mapping>
            <package-type>address</package-type>
            <namespaceURI>urn:AddressBookService</namespaceURI>
        </package-mapping>
        . . .
    </java-wsdl-mapping>
  • <java-xml-type-mapping>

    XML Schema 복합 타입(Complex Type)이나 단순 타입(Simple Type)을 사용할 때 필요하며, XML Schema와 Java 타입 간의 관계를 정의한다. XML Schema에 정의된 built-in 타입이 Java로 표준적인 매핑이 된다면 이 element를 사용하지 않아도 된다.

    <java-wsdl-mapping version="1.1"
        xmlns="http://java.sun.com/xml/ns/j2ee">
        . . .
        <java-xml-type-mapping>
            <java-type>address.Address</java-type>
            <ns1:root-type-qname
                xmlns:ns1=”http://java.sun.com/xml/ns/j2ee”
                xmlns="urn:AddressBookService">
                Address
            </ns1:root-type-qname>
            <qname-scope>complexType</qname-scope>
            <variable-mapping>
                <java-variable-name>addr</java-variable-name>
                <xml-element-name>addr</xml-element-name>
            </variable-mapping>
            <variable-mapping>
                <java-variable-name>street</java-variable-name>
                <xml-element-name>street</xml-element-name>
            </variable-mapping>
            <variable-mapping>
                <java-variable-name>zipcode</java-variable-name>
                <xml-element-name>zipcode</xml-element-name>
            </variable-mapping>
        </java-xml-type-mapping>
        . . .
    </java-wsdl-mapping>
  • <exception-mapping>

    WSDL 결함(fault) 메시지를 Java 예외 클래스로 매핑한다.

    <java-xml-mapping>
        . . .
        <exception-mapping>
            <exception-type>CLASS_NAME</exception-type>
            <wsdl-message>WSDL_MESSAGE_NAME</wsdl-message>
        </exception-mapping>
        . . .
    </java-xml-mapping>
  • <service-interface-mapping>

    WSDL의 서비스 정의를 JAX-RPC 서비스 인터페이스 타입으로 매핑한다.

    <service-interface>는 WSDL의 서비스 정의를 나타내는 Java 인터페이스의 클래스 이름을 정의하고, 서비스 인터페이스의 패키지 이름은 <package-mapping>에 정의된 패키지 이름과 일치해야 한다.

    <port-mapping>는 서비스 인터페이스의 getPortName() 메소드의 포트 이름을 WSDL의 <port>와 대응하게 정의한다.

    <java-xml-mapping…>
        . . .
        <service-interface-mapping>
            <service-interface>
                address.AddressBookService
            </service-interface>
            <ns3:wsdl-service-name
                xmlns:ns3="http://java.sun.com/xml/ns/j2ee"
                xmlns="urn:AddressBookService">
                AddressBookService
            </ns3:wsdl-service-name>
            <port-mapping>
                <port-name>AddressBookIFPort</port-name>
                <java-port-name>AddressBookIFPort</java-port-name>
            </port-mapping>
        </service-interface-mapping>
        . . .
    </java-xml-mapping>

    위와 같이 정의될 경우 생성되는 Java 서비스 인터페이스 정의는 다음과 같다.

    [예 25.8] Java 서비스 인터페이스 정의 : <AddressBookService.java>

    package address;
    
    public interface AddressBookService extends javax.xml.rpc.Service {
    public java.lang.String getAddressBookIFPortAddress();
    public address.AddressBookIF getAddressBookIFPort()
        throws javax.xml.rpc.ServiceException;
    public address.AddressBookIF getAddressBookIFPort(java.net.URL portAddress)
        throws javax.xml.rpc.ServiceException;
    }


  • <service-endpoint-interface-mapping>

    SEI를 WSDL의 portType과 바인딩 정의로 매핑한다. 이 element는 JAX-RPC 컴파일러가 적절한 Endpoint Stub과 Endpoint 인터페이스를 생성할 때 필요한 정보를 제공한다. 또한 WSDL의 operation과 message part 정의가 어떻게 Java Endpoint 메소드의 정의로 매핑될 것인지에 대한 상세 정보를 제공한다.

    다음은 AddressBookService의 매핑 파일에 정의된 예이다.

    <java-wsdl-mapping…>
        . . .
        <service-endpoint-interface-mapping>
            <service-endpoint-interface>
                address.AddressBookIF
            </service-endpoint-interface>
            <ns4:wsdl-port-type
                xmlns:ns4="http://java.sun.com/xml/ns/j2ee"
                xmlns="urn:AddressBookService">
                AddressBookIF
            </ns4:wsdl-port-type>
            <ns5:wsdl-binding
                xmlns:ns5="http://java.sun.com/xml/ns/j2ee"
                xmlns="urn:AddressBookService">
                AddressBookIFSoapBinding
            </ns5:wsdl-binding>
            <service-endpoint-method-mapping>
                <java-method-name>add</java-method-name>
                <wsdl-operation>add</wsdl-operation>
                <wrapped-element/>
                <method-param-parts-mapping>
                    <param-position>0</param-position>
                    <param-type>address.PersonInfo</param-type>
                    <wsdl-message-mapping>
                        <ns6:wsdl-message
                            xmlns:ns6="http://java.sun.com/xml/ns/j2ee"
                            xmlns="urn:AddressBookService">
                            addRequest
                        </ns6:wsdl-message>
                        <wsdl-message-part-name>
                            parameters
                        </wsdl-message-part-name>
                        <parameter-mode>IN</parameter-mode>
                    </wsdl-message-mapping>
                </method-param-parts-mapping>
                <wsdl-return-value-mapping>
                    <method-return-value>
                        address.PersonInfo[]
                    </method-return-value>
                    <ns7:wsdl-message
                        xmlns:ns7=”http://java.sun.com/xml/ns/j2ee“
                        xmlns="urn:AddressBookService">
                        addResponse
                    </ns7:wsdl-message>
                    <wsdl-message-part-name>
                        parameters
                    </wsdl-message-part-name>
                </wsdl-return-value-mapping>
            </service-endpoint-method-mapping>
            . . .
        </service-endpoint-interface-mapping>
        . . .
    </java-wsdl-mapping>