使用Glassfish Metro的动态JAX-WS客户端

时间:2017-02-22 15:14:52

标签: jax-ws

有没有办法用Metro创建动态客户端,就像CXF的JaxWsDynamicClientFactory一样?

1 个答案:

答案 0 :(得分:0)

示例:DynamicClient.java消费公众StockQuote service

package com.scotth.jaxws.dynclient;

import java.io.StringReader;
import java.util.Arrays;
import java.util.List;

import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPConstants;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPFault;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
import javax.xml.ws.Dispatch;
import javax.xml.ws.Service;
import javax.xml.ws.soap.SOAPBinding;
import javax.xml.ws.soap.SOAPFaultException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;

public class DynamicClient {

    /**
     * Demonstrates JAX-WS dynamic client & service invocation
     * Service WSDL: http://www.webservicex.com/stockquote.asmx?WSDL
     * 
     */
    public static void main(String[] args) throws Exception {
        String endpoint = "http://www.webservicex.com/stockquote.asmx";
        QName serviceName = new QName("http://www.webserviceX.NET/", "StockQuote");
        QName portName = new QName(serviceName.getNamespaceURI(),"StockQuoteSoap12");
        Service service = Service.create(serviceName);
        service.addPort(portName, SOAPBinding.SOAP12HTTP_BINDING, endpoint);
        Dispatch<SOAPMessage> dispatch = service.createDispatch(portName, SOAPMessage.class, Service.Mode.MESSAGE);
        MessageFactory mf = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
        SOAPMessage requestMessage = mf.createMessage();
        SOAPPart requestPart = requestMessage.getSOAPPart();
        SOAPEnvelope requestEnvelope = requestPart.getEnvelope();
        requestEnvelope.addNamespaceDeclaration("web", serviceName.getNamespaceURI());
        //SOAPHeader requestHeader = requestEnvelope.getHeader();
        SOAPBody requestBody = requestEnvelope.getBody();
        SOAPElement operationElement = requestBody.addChildElement("GetQuote", "web", serviceName.getNamespaceURI());
        SOAPElement inputArgElement = operationElement.addChildElement("symbol", "web", serviceName.getNamespaceURI());
        inputArgElement.setValue("AAPL");
        requestMessage.saveChanges();
        System.out.println("Web service endpoint: " + endpoint);
        System.out.println("Sending soap request:");
        requestMessage.writeTo(System.out);
        System.out.println("");
        try {
            SOAPMessage responseMessage = dispatch.invoke(requestMessage);
            System.out.println("Received response message:");
            responseMessage.writeTo(System.out);
            System.out.println("");
            SOAPPart responsePart = responseMessage.getSOAPPart();
            SOAPEnvelope responseEnvelope = responsePart.getEnvelope();
            SOAPBody responseBody = responseEnvelope.getBody();
            Node quoteResponseNode = responseBody.getElementsByTagName("GetQuoteResponse").item(0);
            if (quoteResponseNode != null) {
                Node quoteResultNode = quoteResponseNode.getFirstChild();
                if (quoteResultNode != null) {
                    String quoteResultXml = quoteResultNode.getTextContent();
                    System.out.println("Raw quote result xml:\n" + quoteResultXml);
                    if (! "exception".equalsIgnoreCase(quoteResultXml)) {
                        parseQuoteResult(quoteResultXml);
                    } else {
                        System.out.println("Successful SOAP transaction, but service indicates an error. Check the input and retry.");
                    }
                }
            } else {
                System.out.println("No GetQuoteResponse");
            }
        } catch (SOAPFaultException faultException) {
            SOAPFault fault = faultException.getFault();
            String faultCode = fault.getFaultCode();
            String faultMessage = fault.getFaultString();
            System.out.println("Fault: faultcode=" + faultCode + ", reason=" + faultMessage);
        }
    }

    /*
     * <StockQuotes><Stock><Symbol>AAPL</Symbol><Last>136.66</Last><Date>2/24/2017</Date><Time>4:00pm</Time><Change>+0.13</Change><Open>135.91</Open><High>136.66</High><Low>135.28</Low><Volume>21776585</Volume><MktCap>716.99B</MktCap><PreviousClose>136.53</PreviousClose><PercentageChange>+0.10%</PercentageChange><AnnRange>89.47 - 137.48</AnnRange><Earns>8.33</Earns><P-E>16.41</P-E><Name>Apple Inc.</Name></Stock></StockQuotes>
     */
    private static void parseQuoteResult(String quoteResultXml) throws Exception {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document quoteResultDoc = builder.parse(new InputSource(new StringReader(quoteResultXml)));
        Node stockQuotesNode = quoteResultDoc.getElementsByTagName("StockQuotes").item(0);
        Element stockElement = (Element) stockQuotesNode.getFirstChild();
        String[] elementNames = {"Symbol", "Name", "Last", "Date", "Time", "Change", "Open", "High", "Low", "Volume", "MktCap", "PreviousClose", "PercentageChange", "AnnRange", "Earns", "P-E"};
        printStockValues(stockElement, Arrays.asList(elementNames));
    }

    private static void printStockValues(Element stockElement, List<String> elementNames) {
        for (String elementName : elementNames) {
            System.out.println(elementName + ": " + ((Element) stockElement.getElementsByTagName(elementName).item(0)).getTextContent());
        }
    }
}

运行它会产生:

Web service endpoint: http://www.webservicex.com/stockquote.asmx
Sending soap request:
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:web="http://www.webserviceX.NET/"><env:Header/><env:Body><web:GetQuote><web:symbol>AAPL</web:symbol></web:GetQuote></env:Body></env:Envelope>
Received response message:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><env:Header/><soap:Body><GetQuoteResponse xmlns="http://www.webserviceX.NET/"><GetQuoteResult>&lt;StockQuotes&gt;&lt;Stock&gt;&lt;Symbol&gt;AAPL&lt;/Symbol&gt;&lt;Last&gt;136.66&lt;/Last&gt;&lt;Date&gt;2/24/2017&lt;/Date&gt;&lt;Time&gt;4:00pm&lt;/Time&gt;&lt;Change&gt;+0.13&lt;/Change&gt;&lt;Open&gt;135.91&lt;/Open&gt;&lt;High&gt;136.66&lt;/High&gt;&lt;Low&gt;135.28&lt;/Low&gt;&lt;Volume&gt;21776585&lt;/Volume&gt;&lt;MktCap&gt;716.99B&lt;/MktCap&gt;&lt;PreviousClose&gt;136.53&lt;/PreviousClose&gt;&lt;PercentageChange&gt;+0.10%&lt;/PercentageChange&gt;&lt;AnnRange&gt;89.47 - 137.48&lt;/AnnRange&gt;&lt;Earns&gt;8.33&lt;/Earns&gt;&lt;P-E&gt;16.41&lt;/P-E&gt;&lt;Name&gt;Apple Inc.&lt;/Name&gt;&lt;/Stock&gt;&lt;/StockQuotes&gt;</GetQuoteResult></GetQuoteResponse></soap:Body></soap:Envelope>
Raw quote result xml:
<StockQuotes><Stock><Symbol>AAPL</Symbol><Last>136.66</Last><Date>2/24/2017</Date><Time>4:00pm</Time><Change>+0.13</Change><Open>135.91</Open><High>136.66</High><Low>135.28</Low><Volume>21776585</Volume><MktCap>716.99B</MktCap><PreviousClose>136.53</PreviousClose><PercentageChange>+0.10%</PercentageChange><AnnRange>89.47 - 137.48</AnnRange><Earns>8.33</Earns><P-E>16.41</P-E><Name>Apple Inc.</Name></Stock></StockQuotes>
Symbol: AAPL
Name: Apple Inc.
Last: 136.66
Date: 2/24/2017
Time: 4:00pm
Change: +0.13
Open: 135.91
High: 136.66
Low: 135.28
Volume: 21776585
MktCap: 716.99B
PreviousClose: 136.53
PercentageChange: +0.10%
AnnRange: 89.47 - 137.48
Earns: 8.33
P-E: 16.41

来自JAX-WS reference implementation的类路径中的Jars,它是Metro的核心:

FastInfoset.jar           jaxb-impl.jar             policy.jar
axis.jar                  jaxb-jxc.jar              resolver.jar
commons-discovery-0.2.jar jaxb-xjc.jar              saaj-impl.jar
commons-logging.jar       jaxrpc.jar                saaj.jar
gmbal-api-only.jar        jaxws-api.jar             stax-ex.jar
ha-api.jar                jaxws-rt.jar              stax2-api.jar
javax.annotation-api.jar  jaxws-tools.jar           streambuffer.jar
javax.xml.soap-api.jar    jsr181-api.jar            woodstox-core-asl.jar
jaxb-api.jar              management-api.jar        wsdl4j.jar
jaxb-core.jar             mimepull.jar