JAX-WS Dispatch API
Dispatch對象有兩個使用模型:
--消息模型
--負載模型
. 消息模型
在消息模型中,一個Dispatch對象要使用一個完整的消息。完整的消息包括頭與包裝器.
你為Despatch對象指定使用消息模型,當你建立Dispatch對象時,要提供java.xml.Service.Mode.MESSAGE值。
. 負載模型
在負載模型中,Dispatch對象僅使用消息負載(消息體body)。
你為Despatch對象指定使用負載模型,當你建立Dispatch對象時,要提供java.xml.ws.Service.Mode.PAYLOAD值.
2 Data Types(資料類型)
Dispatch對象,因為它們是低級别的對象,使用相同的JAXB生成的進階别的消費者API是不被優化的。
Dispatch對象使用下面幾個類型:
--javax.xml.transform.Source
--javax.xml.soap.SOAPMessage
--javax.activation.DataSource
--JAXB
. 使用Source對象
Dispatch對象能接收與傳回派生自javax.xml.transform.Source接口的對象。 Source對象是儲存xml文檔的低級别對象。
每個Source實作提供方法,通路存儲的xml文檔并操縱它的内容。
下面的對象實作了Source接口:
--DOMSource
--SAXSource
--StreamSource
注意:當使用Source對象時,開發者要負責確定所有必須的且具體的綁定包裝都添加到了消息上。
例如,當一個服務期待SOAP消息互動時,開發人員必須確定所需的SOAP信封添加到傳出的請求
并且SOAP信封的内容是正确的。
. 使用SOAPMessage對象
當下面條件為真時,Dispatch對象能使用javax.xml.soap.SOAPMessage對象。
--Dispatch對象正使用SOAP binding.
--Dispatch對象正使用message mode(消息模型).
. 使用DataSource對象
Dispatch對象能使用實作了javax.activation.DataSource接口的對象,當下面條件為真時:
--Dispatch對象正使用HTTP binding.
--Dispatch對象正使用message mode(消息模型)
DataSource對象提供了一個可以用MIME類型資料的機制,可以來自URL,檔案和位元組數組。
. 使用JAXB對象
雖然Dispatch對象本意是低級别的API, 允許你使用原消息。他們也允許你使用JAXB對象。若要使用
JAXB對象,Dispatch對象必須通過JAXBContext, JAXBContext知道在使用中怎麼編組和解組JAXB對象。
Dispatch對象被建立時通過JAXBContext。
JAXBContext了解你能通過JAXB對象作為invoke()方法的參數。你也能放傳回消息進JAXB對象,JAXBContext
對象能了解。
3 使用Dispatch對象
使用Dispatch對象調用一個遠端服務,你要做以下幾點:
--建立一個Dispatch對象
--建構一個請求消息
--調用合适的invoke()方法
--解析響應消息
. 建立一個Dispatch對象
建立一個Dispatch對象要做以下幾步:
--建立一個Service對象,它代表wsdl:service元素定義的服務
--使用Service對象的createDispatch()方法建立Dispatch對象
public Dispatch<T> createDispatch(QName portName,java.lang.Class<T> type,Service.Mode mode)
throws WebServiceException;
如果你使用JAXB對象的createDispatch()方法的簽名就是:
public Dispatch<T> createDispatch(QName portName,javax.xml.bind.JAXBContext context,Service.Mode mode)
throws WebServiceException;
下表描述createDispatch()方法的參數:
parameter description
partName wsdl:port元素的指定的QName,它代表Dispatch對象調用上的服務提供者。
type 指定Dispatch對象使用的指定對象的資料類型
mode 指定Dispatch對象的消息使用模型。
下面代碼是建立一個Dispatch對象并在消息負載模型下使用DOMSource對象:
...
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);
...
. 建構請求消息(略)
. 同步調用
為消費者生成一個同步調用的響應,你使用Dispatch對象的invoke()方法。
T invoke(T msg) throws WebServiceException;
同步的例子:
...
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);
DOMSource response = disp.invoke(request);
...
. 異步調用
Dispatch對象支援異步調用. Dispatch對象可以使用輪詢與回調兩種方式處理異步。
當使用輪詢方式的invokeAsync()方法時,傳回一個Response<T>對象,可以定期輪詢它,看看response是否傳回。
Response<T> invokeAsync(T msg) throws WebServiceException;
當使用回調方式的invokeAsync()方法時,它接受一個AsyncHandler的實作,當response傳回時處理它。
Future<?> invokeAsync(T msg,AsyncHandler<T> handler) throws WebServiceException;
. 單向調用(OneWay)
當一個請求不需要一個響應的時候,你的遠端調用可以使用Dispatch對象上的invokeOneWay()方法。
void invokeOneWay(T msg) throws WebServiceException;