41장. 원시 XML 메시지 사용

초록

상위 수준 JAX-WS API는 데이터를 JAXB 오브젝트로 마샬링하여 개발자가 네이티브 XML 메시지를 사용하지 못하도록 보호합니다. 그러나 전선을 통과하는 원시 XML 메시지 데이터에 직접 액세스하는 것이 더 나은 경우가 있습니다. JAX-WS API는 원시 XML에 대한 액세스를 제공하는 두 개의 인터페이스를 제공합니다. Dispatch 인터페이스는 클라이언트 측 인터페이스이고 공급자 인터페이스는 서버 측 인터페이스입니다.

41.1. 소비자에서 XML 사용

초록

Dispatch 인터페이스는 원시 메시지에서 직접 작업할 수 있는 하위 수준 JAX-WS API입니다. DOM 개체, SOAP 메시지 및 JAXB 개체를 포함한 여러 유형의 메시지를 수락하고 반환합니다. 낮은 수준의 API이므로 Dispatch 인터페이스는 더 높은 수준의 JAX-WS API가 수행하는 메시지 준비를 수행하지 않습니다. Dispatch 오브젝트에 전달하는 메시지 또는 페이로드가 제대로 구성되어 있고 원격 작업이 호출되는지 확인해야 합니다.

41.1.1. 사용량 모드

41.1.1.1. 개요

디스패치 오브젝트에는 두 가지 사용 모드 가 있습니다.

Dispatch 오브젝트에 지정하는 사용 모드는 사용자 수준 코드로 전달되는 세부 정보 양을 결정합니다.

41.1.1.2. 메시지 모드

메시지 모드에서 Dispatch 오브젝트는 전체 메시지와 함께 작동합니다. 전체 메시지에는 바인딩 특정 헤더 및 래퍼가 포함됩니다. 예를 들어 SOAP 메시지가 필요한 서비스와 상호 작용하는 소비자는 Dispatch 오브젝트의 invoke() 메서드를 완전히 지정된 SOAP 메시지를 제공해야 합니다. invoke() 메서드도 완전히 지정된 SOAP 메시지를 반환합니다. 소비자 코드는 SOAP 메시지의 헤더와 SOAP 메시지의 봉투 정보를 작성하고 읽습니다.

JAXB 오브젝트로 작업할 때 메시지 모드가 적합하지 않습니다.

Dispatch 오브젝트가 메시지 모드를 사용하도록 지정하려면 Dispatch 오브젝트를 생성할 때 java.xml.ws.Service.Mode.MESSAGE 값을 제공합니다. Dispatch 오브젝트 생성에 대한 자세한 내용은 “Dispatch 오브젝트 생성” 을 참조하십시오.

41.1.1.3. 페이로드 모드

페이로드 모드에서 는 메시지 페이로드 모드라고도 하며 Dispatch 오브젝트는 메시지의 페이로드에서만 작동합니다. 예를 들어 페이로드 모드에서 작동하는 Dispatch 오브젝트는 SOAP 메시지의 본문에서만 작동합니다. 바인딩 계층은 바인딩 수준 래퍼 및 헤더를 처리합니다. result가 invoke() 메서드에서 반환되면 바인딩 수준 래퍼 및 헤더가 이미 제거되며 메시지의 본문만 남아 있습니다.

Apache CXF XML 바인딩, 페이로드 모드 및 메시지 모드와 같은 특수 래퍼를 사용하지 않는 바인딩으로 작업하는 경우 동일한 결과를 제공합니다.

Dispatch 오브젝트가 페이로드 모드를 사용하도록 지정하려면 Dispatch 오브젝트를 생성할 때 java.xml.ws.Service.Mode.PAYLOAD 값을 제공합니다. Dispatch 오브젝트 생성에 대한 자세한 내용은 “Dispatch 오브젝트 생성” 을 참조하십시오.

41.1.2. 데이터 유형

41.1.2.1. 개요

Dispatch 개체는 하위 수준 오브젝트이므로 높은 수준의 소비자 API로 동일한 JAXB 생성 유형을 사용하도록 최적화되지 않습니다. 디스패치 오브젝트는 다음 유형의 오브젝트를 사용하여 작동합니다.

41.1.2.2. 소스 오브젝트 사용

Dispatch 개체는 javax.xml.transform.Source 인터페이스에서 파생된 개체를 수락하고 반환합니다. 소스 오브젝트는 바인딩 및 메시지 모드 또는 페이로드 모드에서 지원됩니다.

소스 개체는 XML 문서를 보유하는 낮은 수준의 개체입니다.Source objects are low level objects that hold XML documents. 각 소스 구현은 저장된 XML 문서에 액세스한 다음 해당 콘텐츠를 조작하는 메서드를 제공합니다. 다음 오브젝트는 소스 인터페이스를 구현합니다.

DOMSource
XML 메시지를 Document Object Model(DOM) 트리로 보관합니다. XML 메시지는 getNode() 메서드를 사용하여 액세스하는 Node 오브젝트 세트로 저장됩니다. 노드는 setNode() 메서드를 사용하여 DOM 트리에 업데이트되거나 추가될 수 있습니다.
saXSource
XML 메시지를SAX(Simple API for XML) 개체로 보유하고 있습니다. SAX 오브젝트에는 원시 데이터와 원시 데이터를 구문 분석하는 XMLReader 개체를 보유하는 InputSource 개체가 포함되어 있습니다.
StreamSource
XML 메시지를 데이터 스트림으로 보관합니다. 데이터 스트림은 다른 데이터 스트림과 동일하게 조작될 수 있습니다.

Dispatch 개체를 만들어 일반 소스 개체를 사용하도록 하는 경우 Apache CXF는 메시지를 SAXSource 개체로 반환합니다.

이 동작은 끝점의 source-preferred-format 속성을 사용하여 변경할 수 있습니다. Apache CXF 런타임 구성에 대한 자세한 내용은 IV 부. 웹 서비스 엔드 포인트 구성 을 참조하십시오.

41.1.2.3. SOAPMessage 오브젝트 사용

디스패치 오브젝트는 다음 조건이 true인 경우 javax.xml.soap.SOAPMessage 오브젝트를 사용할 수 있습니다.

  • Dispatch 개체는 SOAP 바인딩을 사용 합니다.The Dispatch object is using the SOAP binding
  • Dispatch 개체는 메시지 모드를 사용합니다.

SOAPMessage 오브젝트에는 SOAP 메시지가 있습니다. 하나의 SOAPPart 오브젝트와 1개 이상의 AttachmentPart 오브젝트가 포함됩니다. SOAPPart 오브젝트에는 SOAP 봉투, 모든 SOAP 헤더 및 SOAP 메시지 본문을 포함한 SOAP 메시지의 SOAP 특정 부분이 포함되어 있습니다. AttachmentPart 오브젝트에는 첨부 파일로 전달되는 바이너리 데이터가 포함되어 있습니다.

41.1.2.4. DataSource 개체 사용

디스패치 오브젝트는 다음 조건이 true인 경우 javax.activation.DataSource 인터페이스를 구현하는 개체를 사용할 수 있습니다.

  • Dispatch 오브젝트는 HTTP 바인딩을 사용하고 있습니다.
  • Dispatch 개체는 메시지 모드를 사용합니다.

데이터 소스 오브젝트는 URL, 파일, 바이트 배열을 포함하여 다양한 소스의 MIME 형식 데이터를 사용하기 위한 메커니즘을 제공합니다.

41.1.2.5. JAXB 오브젝트 사용

Dispatch 개체는 원시 메시지로 작업할 수 있는 낮은 수준의 API를 대상으로 하지만 JAXB 개체로 작업할 수도 있습니다. JAXB 개체를 사용하려면 Dispatch 오브젝트가 사용 중인 JAXB 오브젝트를 마샬링하고 마샬링 해제할 수 있는 JAXBContext 를 전달해야 합니다. Dispatch 오브젝트를 만들 때 JAXBContext 가 전달됩니다.

JAXBContext 개체에서 설명하는 모든 JAXB 오브젝트를 invoke() 메서드에 매개 변수로 전달할 수 있습니다. 반환된 메시지를 JAXBContext 개체에서 이해하는 모든 JAXB 개체로 캐스팅할 수도 있습니다.

JAXBContext 오브젝트 생성에 대한 자세한 내용은 39장. A JAXBContext 오브젝트 사용 을 참조하십시오.

41.1.3. Dispatch Objects 사용

41.1.3.1. 절차

Dispatch 오브젝트를 사용하여 원격 서비스를 호출하려면 다음 시퀀스를 따라야 합니다.

  1. Dispatch 오브젝트를 생성합니다.
  2. 요청 메시지를 구성합니다. ???
  3. 적절한 invoke() 메서드를 호출합니다.
  4. 응답 메시지를 구문 분석합니다.

41.1.3.2. Dispatch 오브젝트 생성

Dispatch 오브젝트를 생성하려면 다음을 수행합니다.

  1. Dispatch 오브젝트가 호출될 서비스 를 정의하는 wsdl:service 요소를 나타내는 Service 오브젝트를 생성합니다. 25.2절. “서비스 오브젝트 생성” 을 참조하십시오.
  2. 예 41.1. “createDispatch() 메서드” 에 표시된 Service 오브젝트의 createDispatch() 메서드를 사용하여 Dispatch 오브젝트를 생성합니다.

    예 41.1. createDispatch() 메서드

    publicDispatch<T>createDispatchQNameportNamejava.lang.Class<T>typeService.ModemodeWebServiceException

    참고

    JAXB 개체를 사용하는 경우 createDispatch() 의 메서드 서명이 있습니다. publicDispatch<T>createDispatchQNameportNamejavax.xml.bind.JAXBContext컨텍스트Service.ModemodeWebServiceException

    표 41.1. “createDispatch()매개변수” createDispatch() 메서드의 매개변수를 설명합니다.

    표 41.1. createDispatch()매개변수

    매개변수설명

    portName

    Dispatch 오브젝트가 호출될 서비스 공급자를 나타내는 wsdl:port 요소의 QName을 지정합니다.

    type

    Dispatch 개체에서 사용하는 개체의 데이터 형식을 지정합니다.Specifies the data type of the objects used by the Dispatch object. 41.1.2절. “데이터 유형” 을 참조하십시오. JAXB 개체를 사용할 때 이 매개 변수는 JAXB 오브젝트를 마샬링 및 unmarshal하는 데 사용되는 JAXBContext 오브젝트를 지정합니다.

    mode

    Dispatch 개체의 사용 모드를 지정합니다.Specifies the usage mode for the Dispatch object. 41.1.1절. “사용량 모드” 을 참조하십시오.

예 41.2. “Dispatch 오브젝트 생성” 페이로드 모드에서 DOMSource 개체로 작동하는 Dispatch 개체를 만드는 코드를 보여 줍니다.Shows the code for creating a Dispatch object that works with DOMSource objects in payload mode.

예 41.2. Dispatch 오브젝트 생성

package com.fusesource.demo;

import javax.xml.namespace.QName;
import javax.xml.ws.Service;

public class Client
{
public static void main(String args[])
  {
    QName serviceName = new QName("http://org.apache.cxf", "stockQuoteReporter");
    Service s = Service.create(serviceName);

    QName portName = new QName("http://org.apache.cxf", "stockQuoteReporterPort");
    Dispatch<DOMSource> dispatch = s.createDispatch(portName,
                                                  DOMSource.class,
                                                  Service.Mode.PAYLOAD);
    ...

41.1.3.3. 요청 메시지 구성

Dispatch 오브젝트를 사용할 때는 처음부터 요청을 빌드해야 합니다. 개발자는 Dispatch 오브젝트에 전달된 메시지가 대상 서비스 공급자가 처리할 수 있는 요청과 일치하는지 확인합니다. 이를 위해서는 서비스 공급자가 사용하는 메시지와 필요한 헤더 정보에 대한 정확한 지식이 필요합니다.

이 정보는 WSDL 문서 또는 메시지를 정의하는 XML 스키마 문서에서 제공할 수 있습니다. 서비스 제공 업체는 크게 다르지만 다음과 같은 몇 가지 지침을 따라야 합니다.

  • 요청의 루트 요소는 호출되는 작업에 해당하는 wsdl:operation 요소의 name 속성 값을 기반으로 합니다.

    주의

    호출 중인 서비스가 doc/literal 베어 메시지를 사용하는 경우 요청의 루트 요소는 wsdl:operation 요소에서 참조하는 wsdl:part 요소의 name 속성 값을 기반으로 합니다.

  • 요청의 루트 요소는 네임스페이스 자격입니다.
  • 호출 중인 서비스가 rpc/literal 메시지를 사용하는 경우 요청의 최상위 요소인 네임스페이스를 사용할 수 없습니다.

    중요

    최상위 수준 요소의 하위 항목은 네임스페이스를 정규화할 수 있습니다. 확인하려면 스키마 정의를 확인해야 합니다.

  • 호출 중인 서비스가 rpc/literal 메시지를 사용하는 경우 최상위 요소 중 어느 것도 null일 수 없습니다.
  • 호출 중인 서비스가 doc/literal 메시지를 사용하는 경우 메시지의 스키마 정의에서 요소에 네임스페이스가 있는지 여부를 결정합니다.

XML 메시지를 사용하는 서비스에 대한 자세한 내용은 WS-I 기본 프로필 를 참조하십시오.

41.1.3.4. 동기 호출

응답을 생성하는 동기 호출을 만드는 소비자의 경우 예 41.3. “Dispatch.invoke() 메서드” 에 표시된 Dispatch 오브젝트의 invoke() 메서드를 사용합니다.

예 41.3. Dispatch.invoke() 메서드

TinvokeTmsgWebServiceException

호출() 메서드에 전달된 응답 및 요청의 유형은 둘 다 Dispatch 오브젝트를 생성할 때 결정됩니다. 예를 들어 createDispatch(portName, SOAPMessage.class, Service.Mode.MESSAGE) 를 사용하여 Dispatch 오브젝트를 생성하는 경우 응답 및 요청 모두 SOAPMessage 오브젝트입니다.

참고

JAXB 개체를 사용하는 경우 응답 및 요청은 제공된 JAXBContext 개체가 마샬링 및 해상할 수 있는 모든 유형일 수 있습니다. 또한 응답 및 요청은 다른 JAXB 오브젝트일 수 있습니다.

예 41.4. “Dispatch 오브젝트를 사용하여 Synchronous Invocation 만들기” DOMSource 개체를 사용하여 원격 서비스에서 동기 호출을 수행하는 코드를 보여 줍니다.Shows code for making a synchronous invocation on a remote service using a DOMSource object.

예 41.4. Dispatch 오브젝트를 사용하여 Synchronous Invocation 만들기

// Creating a DOMSource Object for the request
DocumentBuilder db = DocumentBuilderFactory.newDocumentBuilder();
Document requestDoc = db.newDocument();
Element root = requestDoc.createElementNS("http://org.apache.cxf/stockExample",
                                          "getStockPrice");
root.setNodeValue("DOW");
DOMSource request = new DOMSource(requestDoc);

// Dispatch disp created previously
DOMSource response = disp.invoke(request);

41.1.3.5. 비동기 호출

디스패치 오브젝트도 비동기 호출을 지원합니다. 40장. 비동기 애플리케이션 개발 에서 설명한 상위 수준 비동기 API와 마찬가지로 Dispatch 오브젝트는 폴링 접근 방식과 콜백 접근 방식을 모두 사용할 수 있습니다.

폴링 접근 방식을 사용할 때 invokeAsync() 메서드는 응답이 도착했는지 확인하기 위해 폴링할 수 있는 Response<t > 오브젝트를 반환합니다. 예 41.5. “Polling에 대한 Dispatch.invokeAsync() 메서드” 폴링 방식을 사용하여 비동기 호출을 수행하는 데 사용되는 메서드의 서명을 표시합니다.

예 41.5. Polling에 대한 Dispatch.invokeAsync() 메서드

Response <T>invokeAsyncTmsgWebServiceException

비동기 호출에 대한 폴링 접근 방식을 사용하는 방법에 대한 자세한 내용은 40.4절. “Polling Approach를 사용하여 비동기 클라이언트 구현” 을 참조하십시오.

콜백 방법을 사용할 때 invokeAsync() 메서드는 응답이 반환될 때 AsyncHandler 구현을 사용합니다. 예 41.6. “Dispatch.invokeAsync() 메서드 사용” 콜백 접근 방식을 사용하여 비동기 호출을 만드는 데 사용되는 메서드의 서명을 표시합니다.Shows the signature of the method used to make an asynchronous invocation using the callback approach.

예 41.6. Dispatch.invokeAsync() 메서드 사용

future<?>invokeAsyncTmsgAsyncHandler<T>처리기WebServiceException

비동기 호출에 대한 콜백 접근 방식을 사용하는 방법에 대한 자세한 내용은 40.5절. “Callback Approach를 사용하여 비동기 클라이언트 구현” 을 참조하십시오.

참고

동기 invoke() 메서드와 마찬가지로 응답 유형 및 요청 유형은 Dispatch 오브젝트를 생성할 때 결정됩니다.

41.1.3.6. OneWay 호출

요청이 응답을 생성하지 않으면 Dispatch 오브젝트의 invokeOneWay() 를 사용하여 원격 호출을 수행합니다. 예 41.7. “The Dispatch.invokeOneWay() Method” 이 메서드의 서명을 표시합니다.

예 41.7. The Dispatch.invokeOneWay() Method

invokeOneWayTmsgWebServiceException

요청을 패키징하는 데 사용되는 개체의 유형은 Dispatch 오브젝트를 생성할 때 결정됩니다. 예를 들어, Dispatch 개체가 createDispatch(portName, DOMSource.class, Service.Mode.PAYLOAD) 를 사용하여 생성된 경우 요청은 DOMSource 개체에 패키지됩니다.

참고

JAXB 개체를 사용하는 경우 응답 및 요청은 제공된 JAXBContext 개체가 마샬링 및 unmarshal할 수 있는 모든 유형일 수 있습니다.

예 41.8. “Dispatch Object를 사용하여 One way Invocation을 만드는 방법” JAXB 오브젝트를 사용하여 원격 서비스에서 단방향 호출을 수행하는 코드를 보여줍니다.

예 41.8. Dispatch Object를 사용하여 One way Invocation을 만드는 방법

// Creating a JAXBContext and an Unmarshaller for the request
JAXBContext jbc = JAXBContext.newInstance("org.apache.cxf.StockExample");
Unmarshaller u = jbc.createUnmarshaller();

// Read the request from disk
File rf = new File("request.xml");
GetStockPrice request = (GetStockPrice)u.unmarshal(rf);

// Dispatch disp created previously
disp.invokeOneWay(request);