如何使用代码生成的 SOAP 客户端?

Posted

技术标签:

【中文标题】如何使用代码生成的 SOAP 客户端?【英文标题】:How to use code-generated SOAP client? 【发布时间】:2015-04-27 13:28:35 【问题描述】:

我需要在 java 中为 the EU tax id service 创建一个 Soap 客户端。

我设法使用 wsimport 从 WSDL 生成代码。我的问题是无法弄清楚如何使用它。更具体地说,如何对服务进行 Soap 调用以便验证税号?

我什至尝试了多种方法,使用从 SOAP UI 生成的代码、来自 Intellij 的代码等。它们都完全不同,我有点坚持。有谁能给我点灯好吗?谢谢!

这对我来说似乎相当困难,而且我已经花了这么多小时没有结果。我还尝试了我可以在谷歌上找到的所有教程。我猜这个问题的答案会在未来帮助很多人。

这是生成的代码:

CheckTinService.java:

import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import javax.xml.ws.WebEndpoint;
import javax.xml.ws.WebServiceClient;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.WebServiceFeature;


/**
 * This class was generated by the JAX-WS RI.
 * JAX-WS RI 2.2.4-b01
 * Generated source version: 2.2
 * 
 */
@WebServiceClient(name = "checkTinService", targetNamespace = "urn:ec.europa.eu:taxud:tin:services:checkTin", wsdlLocation = "https://ec.europa.eu/taxation_customs/tin/checkTinService.wsdl")
public class CheckTinService
    extends Service


    private final static URL CHECKTINSERVICE_WSDL_LOCATION;
    private final static WebServiceException CHECKTINSERVICE_EXCEPTION;
    private final static QName CHECKTINSERVICE_QNAME = new QName("urn:ec.europa.eu:taxud:tin:services:checkTin", "checkTinService");

    static 
        URL url = null;
        WebServiceException e = null;
        try 
            url = new URL("https://ec.europa.eu/taxation_customs/tin/checkTinService.wsdl");
         catch (MalformedURLException ex) 
            e = new WebServiceException(ex);
        
        CHECKTINSERVICE_WSDL_LOCATION = url;
        CHECKTINSERVICE_EXCEPTION = e;
    

    public CheckTinService() 
        super(__getWsdlLocation(), CHECKTINSERVICE_QNAME);
    

    public CheckTinService(WebServiceFeature... features) 
        super(__getWsdlLocation(), CHECKTINSERVICE_QNAME);
    

    public CheckTinService(URL wsdlLocation) 
        super(wsdlLocation, CHECKTINSERVICE_QNAME);
    

    public CheckTinService(URL wsdlLocation, WebServiceFeature... features) 
        super(wsdlLocation, CHECKTINSERVICE_QNAME);
    

    public CheckTinService(URL wsdlLocation, QName serviceName) 
        super(wsdlLocation, serviceName);
    

    public CheckTinService(URL wsdlLocation, QName serviceName, WebServiceFeature... features) 
        super(wsdlLocation, serviceName);
    

    /**
     * 
     * @return
     *     returns CheckTinPortType
     */
    @WebEndpoint(name = "checkTinPort")
    public CheckTinPortType getCheckTinPort() 
        return super.getPort(new QName("urn:ec.europa.eu:taxud:tin:services:checkTin", "checkTinPort"), CheckTinPortType.class);
    

    /**
     * 
     * @param features
     *     A list of @link javax.xml.ws.WebServiceFeature to configure on the proxy.  Supported features not in the <code>features</code> parameter will have their default values.
     * @return
     *     returns CheckTinPortType
     */
    @WebEndpoint(name = "checkTinPort")
    public CheckTinPortType getCheckTinPort(WebServiceFeature... features) 
        return super.getPort(new QName("urn:ec.europa.eu:taxud:tin:services:checkTin", "checkTinPort"), CheckTinPortType.class, features);
    

    private static URL __getWsdlLocation() 
        if (CHECKTINSERVICE_EXCEPTION!= null) 
            throw CHECKTINSERVICE_EXCEPTION;
        
        return CHECKTINSERVICE_WSDL_LOCATION;
    


CheckTinPortType.java

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.ws.Holder;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;
import eu.europa.ec.taxud.tin.services.checktin.types.ObjectFactory;


/**
 * This class was generated by the JAX-WS RI.
 * JAX-WS RI 2.2.4-b01
 * Generated source version: 2.2
 * 
 */
@WebService(name = "checkTinPortType", targetNamespace = "urn:ec.europa.eu:taxud:tin:services:checkTin")
@XmlSeeAlso(
    ObjectFactory.class
)
public interface CheckTinPortType 


    /**
     * 
     * @param tinNumber
     * @param countryCode
     * @param validStructure
     * @param requestDate
     * @param validSyntax
     */
    @WebMethod
    @RequestWrapper(localName = "checkTin", targetNamespace = "urn:ec.europa.eu:taxud:tin:services:checkTin:types", className = "eu.europa.ec.taxud.tin.services.checktin.types.CheckTin")
    @ResponseWrapper(localName = "checkTinResponse", targetNamespace = "urn:ec.europa.eu:taxud:tin:services:checkTin:types", className = "eu.europa.ec.taxud.tin.services.checktin.types.CheckTinResponse")
    public void checkTin(
        @WebParam(name = "countryCode", targetNamespace = "urn:ec.europa.eu:taxud:tin:services:checkTin:types", mode = WebParam.Mode.INOUT)
        Holder<String> countryCode,
        @WebParam(name = "tinNumber", targetNamespace = "urn:ec.europa.eu:taxud:tin:services:checkTin:types", mode = WebParam.Mode.INOUT)
        Holder<String> tinNumber,
        @WebParam(name = "requestDate", targetNamespace = "urn:ec.europa.eu:taxud:tin:services:checkTin:types", mode = WebParam.Mode.OUT)
        Holder<XMLGregorianCalendar> requestDate,
        @WebParam(name = "validStructure", targetNamespace = "urn:ec.europa.eu:taxud:tin:services:checkTin:types", mode = WebParam.Mode.OUT)
        Holder<Boolean> validStructure,
        @WebParam(name = "validSyntax", targetNamespace = "urn:ec.europa.eu:taxud:tin:services:checkTin:types", mode = WebParam.Mode.OUT)
        Holder<Boolean> validSyntax);


ObjectFactory.java:

import com.exiqon.core.eu.europa.ec.taxud.tin.services.checktin.types.CheckTin;
import com.exiqon.core.eu.europa.ec.taxud.tin.services.checktin.types.CheckTinResponse;

import javax.xml.bind.annotation.XmlRegistry;


/**
 * This object contains factory methods for each 
 * Java content interface and Java element interface 
 * generated in the eu.europa.ec.taxud.tin.services.checktin.types package. 
 * <p>An ObjectFactory allows you to programatically 
 * construct new instances of the Java representation 
 * for XML content. The Java representation of XML 
 * content can consist of schema derived interfaces 
 * and classes representing the binding of schema 
 * type definitions, element declarations and model 
 * groups.  Factory methods for each of these are 
 * provided in this class.
 * 
 */
@XmlRegistry
public class ObjectFactory 


    /**
     * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: eu.europa.ec.taxud.tin.services.checktin.types
     * 
     */
    public ObjectFactory() 
    

    /**
     * Create an instance of @link eu.europa.ec.taxud.tin.services.checktin.types.CheckTin 
     * 
     */
    public CheckTin createCheckTin() 
        return new CheckTin();
    

    /**
     * Create an instance of @link CheckTinResponse 
     * 
     */
    public CheckTinResponse createCheckTinResponse() 
        return new CheckTinResponse();
    


CheckTinResponse.java:

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSchemaType;
import javax.xml.bind.annotation.XmlType;
import javax.xml.datatype.XMLGregorianCalendar;


/**
 * <p>Java class for anonymous complex type.
 * 
 * <p>The following schema fragment specifies the expected content contained within this class.
 * 
 * <pre>
 * &lt;complexType>
 *   &lt;complexContent>
 *     &lt;restriction base="http://www.w3.org/2001/XMLSchemaanyType">
 *       &lt;sequence>
 *         &lt;element name="countryCode" type="http://www.w3.org/2001/XMLSchemastring"/>
 *         &lt;element name="tinNumber" type="http://www.w3.org/2001/XMLSchemastring"/>
 *         &lt;element name="requestDate" type="http://www.w3.org/2001/XMLSchemadate"/>
 *         &lt;element name="validStructure" type="http://www.w3.org/2001/XMLSchemaboolean"/>
 *         &lt;element name="validSyntax" type="http://www.w3.org/2001/XMLSchemaboolean" minOccurs="0"/>
 *       &lt;/sequence>
 *     &lt;/restriction>
 *   &lt;/complexContent>
 * &lt;/complexType>
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = 
    "countryCode",
    "tinNumber",
    "requestDate",
    "validStructure",
    "validSyntax"
)
@XmlRootElement(name = "checkTinResponse")
public class CheckTinResponse 

    @XmlElement(required = true)
    protected String countryCode;
    @XmlElement(required = true)
    protected String tinNumber;
    @XmlElement(required = true)
    @XmlSchemaType(name = "date")
    protected XMLGregorianCalendar requestDate;
    protected boolean validStructure;
    protected Boolean validSyntax;

    /**
     * Gets the value of the countryCode property.
     * 
     * @return
     *     possible object is
     *     @link String 
     *     
     */
    public String getCountryCode() 
        return countryCode;
    

    /**
     * Sets the value of the countryCode property.
     * 
     * @param value
     *     allowed object is
     *     @link String 
     *     
     */
    public void setCountryCode(String value) 
        this.countryCode = value;
    

    /**
     * Gets the value of the tinNumber property.
     * 
     * @return
     *     possible object is
     *     @link String 
     *     
     */
    public String getTinNumber() 
        return tinNumber;
    

    /**
     * Sets the value of the tinNumber property.
     * 
     * @param value
     *     allowed object is
     *     @link String 
     *     
     */
    public void setTinNumber(String value) 
        this.tinNumber = value;
    

    /**
     * Gets the value of the requestDate property.
     * 
     * @return
     *     possible object is
     *     @link XMLGregorianCalendar 
     *     
     */
    public XMLGregorianCalendar getRequestDate() 
        return requestDate;
    

    /**
     * Sets the value of the requestDate property.
     * 
     * @param value
     *     allowed object is
     *     @link XMLGregorianCalendar 
     *     
     */
    public void setRequestDate(XMLGregorianCalendar value) 
        this.requestDate = value;
    

    /**
     * Gets the value of the validStructure property.
     * 
     */
    public boolean isValidStructure() 
        return validStructure;
    

    /**
     * Sets the value of the validStructure property.
     * 
     */
    public void setValidStructure(boolean value) 
        this.validStructure = value;
    

    /**
     * Gets the value of the validSyntax property.
     * 
     * @return
     *     possible object is
     *     @link Boolean 
     *     
     */
    public Boolean isValidSyntax() 
        return validSyntax;
    

    /**
     * Sets the value of the validSyntax property.
     * 
     * @param value
     *     allowed object is
     *     @link Boolean 
     *     
     */
    public void setValidSyntax(Boolean value) 
        this.validSyntax = value;
    


CheckTin.java:

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;


/**
 * <p>Java class for anonymous complex type.
 * 
 * <p>The following schema fragment specifies the expected content contained within this class.
 * 
 * <pre>
 * &lt;complexType>
 *   &lt;complexContent>
 *     &lt;restriction base="http://www.w3.org/2001/XMLSchemaanyType">
 *       &lt;sequence>
 *         &lt;element name="countryCode" type="http://www.w3.org/2001/XMLSchemastring"/>
 *         &lt;element name="tinNumber" type="http://www.w3.org/2001/XMLSchemastring"/>
 *       &lt;/sequence>
 *     &lt;/restriction>
 *   &lt;/complexContent>
 * &lt;/complexType>
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = 
    "countryCode",
    "tinNumber"
)
@XmlRootElement(name = "checkTin")
public class CheckTin 

    @XmlElement(required = true)
    protected String countryCode;
    @XmlElement(required = true)
    protected String tinNumber;

    /**
     * Gets the value of the countryCode property.
     * 
     * @return
     *     possible object is
     *     @link String 
     *     
     */
    public String getCountryCode() 
        return countryCode;
    

    /**
     * Sets the value of the countryCode property.
     * 
     * @param value
     *     allowed object is
     *     @link String 
     *     
     */
    public void setCountryCode(String value) 
        this.countryCode = value;
    

    /**
     * Gets the value of the tinNumber property.
     * 
     * @return
     *     possible object is
     *     @link String 
     *     
     */
    public String getTinNumber() 
        return tinNumber;
    

    /**
     * Sets the value of the tinNumber property.
     * 
     * @param value
     *     allowed object is
     *     @link String 
     *     
     */
    public void setTinNumber(String value) 
        this.tinNumber = value;
    


【问题讨论】:

【参考方案1】:

示例客户端代码。

public class WsTest 

    public static void main(String[] args) 
        try 
            CheckTinService checkTinService = new CheckTinService();
            CheckTinPortType portType = checkTinService.getPort(CheckTinPortType.class);
            Holder<String> code = new Holder<String>("DE");
            Holder<String> tin = new Holder<String>("12346789");
            Holder<XMLGregorianCalendar> requestDate = new Holder<>();
            Holder<Boolean> validStructure = new Holder<>();
            Holder<Boolean> validSyntax = new Holder<>();
            portType.checkTin(code, tin, requestDate, validStructure, validSyntax);

            System.out.println("requestDate : " + requestDate.value);
            System.out.println("validStructure : " + validStructure.value);
            System.out.println("validSyntax : " + validSyntax.value);
         catch (Exception e) 
            e.printStackTrace();
        
    


您还可以为响应肥皂消息添加处理程序。

或来自soap UI:发送以下请求

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:ec.europa.eu:taxud:tin:services:checkTin:types">
   <soapenv:Header/>
   <soapenv:Body>
      <urn:checkTin>
         <urn:countryCode>DE</urn:countryCode>
         <urn:tinNumber>12346789</urn:tinNumber>
      </urn:checkTin>
   </soapenv:Body>
</soapenv:Envelope>

【讨论】:

【参考方案2】:

这里有什么问题?

通过调用正确初始化的CheckTinServicegetCheckTinPort() 来获取CheckTinPortType,并使用它来执行调用。

所有必要的类都生成了,您现在只需使用适当的参数执行checkTin() 调用。

【讨论】:

谢谢卡亚曼。 CheckTinPortType 的实例可以安全地被 Web 应用程序的所有用户共享吗?或者每个用户应该有一个 CheckTinPortType,甚至每个请求一个?

以上是关于如何使用代码生成的 SOAP 客户端?的主要内容,如果未能解决你的问题,请参考以下文章

如何解析从文件加载的soap消息?

如何在 JAVA 中使用 UsernameToken 创建 SOAP API 请求?

在构建 SOAP API 时如何使用 SSL?

如何查看 PHP SOAP 客户端类生成的实际 XML?

如何使用 Ruby 的 SOAP::Attachment 类?

如何使用 WSDL 将用户代理添加到自动生成的肥皂客户端