使用Java中的XML SOAP Webservice

时间:2012-01-30 22:56:47

标签: java xml web-services soap

我需要知道在Java中使用XML SOAP Web服务的最佳方法是什么。我需要发送以下请求:

POST /cfdi/wsTimbrado.asmx HTTP/1.1
Host: test.timbrado.com.mx
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "https://test.timbrado.com.mx/cfdi/GeneraTimbre"

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header>
    <AuthenticationHeader xmlns="https://test.timbrado.com.mx/cfdi/">
      <UserName>string</UserName>
      <Password>string</Password>
    </AuthenticationHeader>
  </soap:Header>
  <soap:Body>
    <GeneraTimbre xmlns="https://test.timbrado.com.mx/cfdi/">
      <xmlBytes>base64Binary</xmlBytes>
    </GeneraTimbre>
  </soap:Body>
</soap:Envelope>

作为回复,我收到以下内容:

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header>
    <Error xmlns="https://test.timbrado.com.mx/cfdi/">
      <DescripcionError>string</DescripcionError>
      <Codigo>string</Codigo>
    </Error>
  </soap:Header>
  <soap:Body>
    <GeneraTimbreResponse xmlns="https://test.timbrado.com.mx/cfdi/">
      <GeneraTimbreResult>string</GeneraTimbreResult>
    </GeneraTimbreResponse>
  </soap:Body>
</soap:Envelope>

SOAP XML Web服务的合同如下:

<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="https://test.timbrado.com.mx/cfdi/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" targetNamespace="https://test.timbrado.com.mx/cfdi/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
  <wsdl:types>
    <s:schema elementFormDefault="qualified" targetNamespace="https://test.timbrado.com.mx/cfdi/">
      <s:element name="GeneraTimbre">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="xmlBytes" type="s:base64Binary" />
          </s:sequence>
        </s:complexType>
      </s:element>
      <s:element name="GeneraTimbreResponse">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="GeneraTimbreResult" type="s:string" />
          </s:sequence>
        </s:complexType>
      </s:element>
      <s:element name="AuthenticationHeader" type="tns:AuthenticationHeader" />
      <s:complexType name="AuthenticationHeader">
        <s:sequence>
          <s:element minOccurs="0" maxOccurs="1" name="UserName" type="s:string" />
          <s:element minOccurs="0" maxOccurs="1" name="Password" type="s:string" />
        </s:sequence>
        <s:anyAttribute />
      </s:complexType>
      <s:element name="Error" type="tns:Error" />
      <s:complexType name="Error">
        <s:sequence>
          <s:element minOccurs="0" maxOccurs="1" name="DescripcionError" type="s:string" />
          <s:element minOccurs="0" maxOccurs="1" name="Codigo" type="s:string" />
        </s:sequence>
        <s:anyAttribute />
      </s:complexType>
    </s:schema>
  </wsdl:types>
  <wsdl:message name="GeneraTimbreSoapIn">
    <wsdl:part name="parameters" element="tns:GeneraTimbre" />
  </wsdl:message>
  <wsdl:message name="GeneraTimbreSoapOut">
    <wsdl:part name="parameters" element="tns:GeneraTimbreResponse" />
  </wsdl:message>
  <wsdl:message name="GeneraTimbreAuthenticationHeader">
    <wsdl:part name="AuthenticationHeader" element="tns:AuthenticationHeader" />
  </wsdl:message>
  <wsdl:message name="GeneraTimbreError">
    <wsdl:part name="Error" element="tns:Error" />
  </wsdl:message>
  <wsdl:portType name="ServicioTimbradoPruebasSoap">
    <wsdl:operation name="GeneraTimbre">
      <wsdl:input message="tns:GeneraTimbreSoapIn" />
      <wsdl:output message="tns:GeneraTimbreSoapOut" />
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="ServicioTimbradoPruebasSoap" type="tns:ServicioTimbradoPruebasSoap">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
    <wsdl:operation name="GeneraTimbre">
      <soap:operation soapAction="https://test.timbrado.com.mx/cfdi/GeneraTimbre" style="document" />
      <wsdl:input>
        <soap:body use="literal" />
        <soap:header message="tns:GeneraTimbreAuthenticationHeader" part="AuthenticationHeader" use="literal" />
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal" />
        <soap:header message="tns:GeneraTimbreError" part="Error" use="literal" />
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:binding name="ServicioTimbradoPruebasSoap12" type="tns:ServicioTimbradoPruebasSoap">
    <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />
    <wsdl:operation name="GeneraTimbre">
      <soap12:operation soapAction="https://test.timbrado.com.mx/cfdi/GeneraTimbre" style="document" />
      <wsdl:input>
        <soap12:body use="literal" />
        <soap12:header message="tns:GeneraTimbreAuthenticationHeader" part="AuthenticationHeader" use="literal" />
      </wsdl:input>
      <wsdl:output>
        <soap12:body use="literal" />
        <soap12:header message="tns:GeneraTimbreError" part="Error" use="literal" />
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="ServicioTimbradoPruebas">
    <wsdl:port name="ServicioTimbradoPruebasSoap" binding="tns:ServicioTimbradoPruebasSoap">
      <soap:address location="https://test.timbrado.com.mx/cfdi/wstimbrado.asmx" />
    </wsdl:port>
    <wsdl:port name="ServicioTimbradoPruebasSoap12" binding="tns:ServicioTimbradoPruebasSoap12">
      <soap12:address location="https://test.timbrado.com.mx/cfdi/wstimbrado.asmx" />
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

使用eclipse,我创建了WebService Client,我得到了以下类:

  • ServicioTimbradoPruebas.java
  • ServicioTimbradoPruebasLocator.java
  • ServicioTimbradoPruebasSoap.java
  • ServicioTimbradoPruebasSoapProxy.java
  • ServicioTimbradoPruebasSoapStub.java

java类具有以下结构:

ServicioTimbradoPruebas.java:

package mx.com.timbrado.test.cfdi;

public interface ServicioTimbradoPruebas extends javax.xml.rpc.Service {
    public java.lang.String getServicioTimbradoPruebasSoapAddress();

    public mx.com.timbrado.test.cfdi.ServicioTimbradoPruebasSoap getServicioTimbradoPruebasSoap() throws javax.xml.rpc.ServiceException;

    public mx.com.timbrado.test.cfdi.ServicioTimbradoPruebasSoap getServicioTimbradoPruebasSoap(java.net.URL portAddress) throws javax.xml.rpc.ServiceException;
}

ServicioTimbradoPruebasLocator.java:

package mx.com.timbrado.test.cfdi;

public class ServicioTimbradoPruebasLocator extends org.apache.axis.client.Service implements mx.com.timbrado.test.cfdi.ServicioTimbradoPruebas {

    public ServicioTimbradoPruebasLocator() {
    }


    public ServicioTimbradoPruebasLocator(org.apache.axis.EngineConfiguration config) {
        super(config);
    }

    public ServicioTimbradoPruebasLocator(java.lang.String wsdlLoc, javax.xml.namespace.QName sName) throws javax.xml.rpc.ServiceException {
        super(wsdlLoc, sName);
    }

    // Use to get a proxy class for ServicioTimbradoPruebasSoap
    private java.lang.String ServicioTimbradoPruebasSoap_address = "https://test.timbrado.com.mx/cfdi/wstimbrado.asmx";

    public java.lang.String getServicioTimbradoPruebasSoapAddress() {
        return ServicioTimbradoPruebasSoap_address;
    }

    // The WSDD service name defaults to the port name.
    private java.lang.String ServicioTimbradoPruebasSoapWSDDServiceName = "ServicioTimbradoPruebasSoap";

    public java.lang.String getServicioTimbradoPruebasSoapWSDDServiceName() {
        return ServicioTimbradoPruebasSoapWSDDServiceName;
    }

    public void setServicioTimbradoPruebasSoapWSDDServiceName(java.lang.String name) {
        ServicioTimbradoPruebasSoapWSDDServiceName = name;
    }

    public mx.com.timbrado.test.cfdi.ServicioTimbradoPruebasSoap getServicioTimbradoPruebasSoap() throws javax.xml.rpc.ServiceException {
       java.net.URL endpoint;
        try {
            endpoint = new java.net.URL(ServicioTimbradoPruebasSoap_address);
        }
        catch (java.net.MalformedURLException e) {
            throw new javax.xml.rpc.ServiceException(e);
        }
        return getServicioTimbradoPruebasSoap(endpoint);
    }

    public mx.com.timbrado.test.cfdi.ServicioTimbradoPruebasSoap getServicioTimbradoPruebasSoap(java.net.URL portAddress) throws javax.xml.rpc.ServiceException {
        try {
            mx.com.timbrado.test.cfdi.ServicioTimbradoPruebasSoapStub _stub = new mx.com.timbrado.test.cfdi.ServicioTimbradoPruebasSoapStub(portAddress, this);
            _stub.setPortName(getServicioTimbradoPruebasSoapWSDDServiceName());
            return _stub;
        }
        catch (org.apache.axis.AxisFault e) {
            return null;
        }
    }

    public void setServicioTimbradoPruebasSoapEndpointAddress(java.lang.String address) {
        ServicioTimbradoPruebasSoap_address = address;
    }

    /**
     * For the given interface, get the stub implementation.
     * If this service has no port for the given interface,
     * then ServiceException is thrown.
     */
    public java.rmi.Remote getPort(Class serviceEndpointInterface) throws javax.xml.rpc.ServiceException {
        try {
            if (mx.com.timbrado.test.cfdi.ServicioTimbradoPruebasSoap.class.isAssignableFrom(serviceEndpointInterface)) {
                mx.com.timbrado.test.cfdi.ServicioTimbradoPruebasSoapStub _stub = new mx.com.timbrado.test.cfdi.ServicioTimbradoPruebasSoapStub(new java.net.URL(ServicioTimbradoPruebasSoap_address), this);
                _stub.setPortName(getServicioTimbradoPruebasSoapWSDDServiceName());
                return _stub;
            }
        }
        catch (java.lang.Throwable t) {
            throw new javax.xml.rpc.ServiceException(t);
        }
        throw new javax.xml.rpc.ServiceException("There is no stub implementation for the interface:  " + (serviceEndpointInterface == null ? "null" : serviceEndpointInterface.getName()));
    }

    /**
     * For the given interface, get the stub implementation.
     * If this service has no port for the given interface,
     * then ServiceException is thrown.
     */
    public java.rmi.Remote getPort(javax.xml.namespace.QName portName, Class serviceEndpointInterface) throws javax.xml.rpc.ServiceException {
        if (portName == null) {
            return getPort(serviceEndpointInterface);
        }
        java.lang.String inputPortName = portName.getLocalPart();
        if ("ServicioTimbradoPruebasSoap".equals(inputPortName)) {
            return getServicioTimbradoPruebasSoap();
        }
        else  {
            java.rmi.Remote _stub = getPort(serviceEndpointInterface);
            ((org.apache.axis.client.Stub) _stub).setPortName(portName);
            return _stub;
        }
    }

    public javax.xml.namespace.QName getServiceName() {
        return new javax.xml.namespace.QName("https://test.timbrado.com.mx/cfdi/", "ServicioTimbradoPruebas");
    }

    private java.util.HashSet ports = null;

    public java.util.Iterator getPorts() {
        if (ports == null) {
            ports = new java.util.HashSet();
            ports.add(new javax.xml.namespace.QName("https://test.timbrado.com.mx/cfdi/", "ServicioTimbradoPruebasSoap"));
        }
        return ports.iterator();
    }

    /**
    * Set the endpoint address for the specified port name.
    */
    public void setEndpointAddress(java.lang.String portName, java.lang.String address) throws javax.xml.rpc.ServiceException {

if ("ServicioTimbradoPruebasSoap".equals(portName)) {
            setServicioTimbradoPruebasSoapEndpointAddress(address);
        }
        else 
{ // Unknown Port Name
            throw new javax.xml.rpc.ServiceException(" Cannot set Endpoint Address for Unknown Port" + portName);
        }
    }

    /**
    * Set the endpoint address for the specified port name.
    */
    public void setEndpointAddress(javax.xml.namespace.QName portName, java.lang.String address) throws javax.xml.rpc.ServiceException {
        setEndpointAddress(portName.getLocalPart(), address);
    }

}

ServicioTimbradoPruebasSoap.java:

package mx.com.timbrado.test.cfdi;

public interface ServicioTimbradoPruebasSoap extends java.rmi.Remote {
    public java.lang.String generaTimbre(byte[] xmlBytes) throws java.rmi.RemoteException;
}

ServicioTimbradoPruebasSoapProxy.java:

package mx.com.timbrado.test.cfdi;

public class ServicioTimbradoPruebasSoapProxy implements mx.com.timbrado.test.cfdi.ServicioTimbradoPruebasSoap {
  private String _endpoint = null;
  private mx.com.timbrado.test.cfdi.ServicioTimbradoPruebasSoap servicioTimbradoPruebasSoap = null;

  public ServicioTimbradoPruebasSoapProxy() {
    _initServicioTimbradoPruebasSoapProxy();
  }

  public ServicioTimbradoPruebasSoapProxy(String endpoint) {
    _endpoint = endpoint;
    _initServicioTimbradoPruebasSoapProxy();
  }

  private void _initServicioTimbradoPruebasSoapProxy() {
    try {
      servicioTimbradoPruebasSoap = (new mx.com.timbrado.test.cfdi.ServicioTimbradoPruebasLocator()).getServicioTimbradoPruebasSoap();
      if (servicioTimbradoPruebasSoap != null) {
        if (_endpoint != null)
          ((javax.xml.rpc.Stub)servicioTimbradoPruebasSoap)._setProperty("javax.xml.rpc.service.endpoint.address", _endpoint);
        else
          _endpoint = (String)((javax.xml.rpc.Stub)servicioTimbradoPruebasSoap)._getProperty("javax.xml.rpc.service.endpoint.address");
      }

    }
    catch (javax.xml.rpc.ServiceException serviceException) {}
  }

  public String getEndpoint() {
    return _endpoint;
  }

  public void setEndpoint(String endpoint) {
    _endpoint = endpoint;
    if (servicioTimbradoPruebasSoap != null)
      ((javax.xml.rpc.Stub)servicioTimbradoPruebasSoap)._setProperty("javax.xml.rpc.service.endpoint.address", _endpoint);

  }

  public mx.com.timbrado.test.cfdi.ServicioTimbradoPruebasSoap getServicioTimbradoPruebasSoap() {
    if (servicioTimbradoPruebasSoap == null)
      _initServicioTimbradoPruebasSoapProxy();
    return servicioTimbradoPruebasSoap;
  }

  public java.lang.String generaTimbre(byte[] xmlBytes) throws java.rmi.RemoteException{
    if (servicioTimbradoPruebasSoap == null)
      _initServicioTimbradoPruebasSoapProxy();
    return servicioTimbradoPruebasSoap.generaTimbre(xmlBytes);
  }


}

ServicioTimbradoPruebasSoapStub.java:

package mx.com.timbrado.test.cfdi;

public class ServicioTimbradoPruebasSoapStub extends org.apache.axis.client.Stub implements mx.com.timbrado.test.cfdi.ServicioTimbradoPruebasSoap {
    private java.util.Vector cachedSerClasses = new java.util.Vector();
    private java.util.Vector cachedSerQNames = new java.util.Vector();
    private java.util.Vector cachedSerFactories = new java.util.Vector();
    private java.util.Vector cachedDeserFactories = new java.util.Vector();

    static org.apache.axis.description.OperationDesc [] _operations;

    static {
        _operations = new org.apache.axis.description.OperationDesc[1];
        _initOperationDesc1();
    }

    private static void _initOperationDesc1(){
        org.apache.axis.description.OperationDesc oper;
        org.apache.axis.description.ParameterDesc param;
        oper = new org.apache.axis.description.OperationDesc();
        oper.setName("GeneraTimbre");
        param = new org.apache.axis.description.ParameterDesc(new javax.xml.namespace.QName("https://test.timbrado.com.mx/cfdi/", "xmlBytes"), org.apache.axis.description.ParameterDesc.IN, new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "base64Binary"), byte[].class, false, false);
        param.setOmittable(true);
        oper.addParameter(param);
        oper.setReturnType(new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"));
        oper.setReturnClass(java.lang.String.class);
        oper.setReturnQName(new javax.xml.namespace.QName("https://test.timbrado.com.mx/cfdi/", "GeneraTimbreResult"));
        oper.setStyle(org.apache.axis.constants.Style.WRAPPED);
        oper.setUse(org.apache.axis.constants.Use.LITERAL);
        _operations[0] = oper;

    }

    public ServicioTimbradoPruebasSoapStub() throws org.apache.axis.AxisFault {
         this(null);
    }

    public ServicioTimbradoPruebasSoapStub(java.net.URL endpointURL, javax.xml.rpc.Service service) throws org.apache.axis.AxisFault {
         this(service);
         super.cachedEndpoint = endpointURL;
    }

    public ServicioTimbradoPruebasSoapStub(javax.xml.rpc.Service service) throws org.apache.axis.AxisFault {
        if (service == null) {
            super.service = new org.apache.axis.client.Service();
        } else {
            super.service = service;
        }
        ((org.apache.axis.client.Service)super.service).setTypeMappingVersion("1.2");
    }

    protected org.apache.axis.client.Call createCall() throws java.rmi.RemoteException {
        try {
            org.apache.axis.client.Call _call = super._createCall();
            if (super.maintainSessionSet) {
                _call.setMaintainSession(super.maintainSession);
            }
            if (super.cachedUsername != null) {
                _call.setUsername(super.cachedUsername);
            }
            if (super.cachedPassword != null) {
                _call.setPassword(super.cachedPassword);
            }
            if (super.cachedEndpoint != null) {
                _call.setTargetEndpointAddress(super.cachedEndpoint);
            }
            if (super.cachedTimeout != null) {
                _call.setTimeout(super.cachedTimeout);
            }
            if (super.cachedPortName != null) {
                _call.setPortName(super.cachedPortName);
            }
            java.util.Enumeration keys = super.cachedProperties.keys();
            while (keys.hasMoreElements()) {
                java.lang.String key = (java.lang.String) keys.nextElement();
                _call.setProperty(key, super.cachedProperties.get(key));
            }
            return _call;
        }
        catch (java.lang.Throwable _t) {
            throw new org.apache.axis.AxisFault("Failure trying to get the Call object", _t);
        }
    }

    public java.lang.String generaTimbre(byte[] xmlBytes) throws java.rmi.RemoteException {
        if (super.cachedEndpoint == null) {
            throw new org.apache.axis.NoEndPointException();
        }
        org.apache.axis.client.Call _call = createCall();
        _call.setOperation(_operations[0]);
        _call.setUseSOAPAction(true);
        _call.setSOAPActionURI("https://test.timbrado.com.mx/cfdi/GeneraTimbre");
        _call.setEncodingStyle(null);
        _call.setProperty(org.apache.axis.client.Call.SEND_TYPE_ATTR, Boolean.FALSE);
        _call.setProperty(org.apache.axis.AxisEngine.PROP_DOMULTIREFS, Boolean.FALSE);
        _call.setSOAPVersion(org.apache.axis.soap.SOAPConstants.SOAP11_CONSTANTS);
        _call.setOperationName(new javax.xml.namespace.QName("https://test.timbrado.com.mx/cfdi/", "GeneraTimbre"));

        setRequestHeaders(_call);
        setAttachments(_call);
 try {        java.lang.Object _resp = _call.invoke(new java.lang.Object[] {xmlBytes});

        if (_resp instanceof java.rmi.RemoteException) {
            throw (java.rmi.RemoteException)_resp;
        }
        else {
            extractAttachments(_call);
            try {
                return (java.lang.String) _resp;
            } catch (java.lang.Exception _exception) {
                return (java.lang.String) org.apache.axis.utils.JavaUtils.convert(_resp, java.lang.String.class);
            }
        }
  } catch (org.apache.axis.AxisFault axisFaultException) {
  throw axisFaultException;
}
    }

}

我该怎样做才能发送请求并从网络服务接收回复?

1 个答案:

答案 0 :(得分:2)

JAX-WS允许您基于Web服务的WSDL创建客户端。您可以查看reference implementationCXF(查找有关实施网络服务客户端的教程)。