Web services 具有用户定义类型的JAX-WS

Web services 具有用户定义类型的JAX-WS,web-services,jaxb,jax-ws,java-ee-7,Web Services,Jaxb,Jax Ws,Java Ee 7,我试图学习JAX-WS,特别是如何使用复杂类型。在我接触过的所有三本关于JavaEE的书中,他们都提到这是可能的,但没有给出任何例子。。。奇怪的是,网络上的搜索都没有找到一个完整的——包括服务和客户端,但也许我就是找不到它 以下是服务类别: package userobj; import javax.jws.WebService; import javax.jws.WebMethod; import javax.jws.WebParam; @WebService(serviceName

我试图学习JAX-WS,特别是如何使用复杂类型。在我接触过的所有三本关于JavaEE的书中,他们都提到这是可能的,但没有给出任何例子。。。奇怪的是,网络上的搜索都没有找到一个完整的——包括服务和客户端,但也许我就是找不到它

以下是服务类别:

package userobj;    
import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.jws.WebParam;

@WebService(serviceName = "UserObj")
public class UserObj 
{    
    @WebMethod(operationName = "sum")
    public int sum(@WebParam(name = "obj") Two obj) 
    {
        return obj.getA() + obj.getB();
    }
}
以及对应的复杂类型2的类:

package userobj;
public class Two 
{           
        private int a, b;
        public int getA() { return a; }
        public void setA(int newA) { a = newA; }
        public int getB() { return b; }
        public void setB(int newB) { b = newB; }
}
当我尝试在客户端Web服务应用程序中使用它时,Glassfish4.1会自动从生成的 第二类是这样的:

package uowsapp;

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


/**
 * <p>Java class for two complex type.
 * 
 * <p>The following schema fragment specifies the expected content contained within this class.
 * 
 * <pre>
 * &lt;complexType name="two">
 *   &lt;complexContent>
 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       &lt;sequence>
 *       &lt;/sequence>
 *     &lt;/restriction>
 *   &lt;/complexContent>
 * &lt;/complexType>
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "two")
public class Two {


}
com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions
Class has two properties of the same name "a"
    this problem is related to the following location:
        at public int userobj.Two.getA()
        at userobj.Two
        at public userobj.Two userobj.jaxws.Sum.obj
        at userobj.jaxws.Sum
    this problem is related to the following location:
        at private int userobj.Two.a
        at userobj.Two
        at public userobj.Two userobj.jaxws.Sum.obj
        at userobj.jaxws.Sum
在部署服务的应用程序期间导致以下异常,并且部署失败:

@XmlRootElement(name="Two")
public class Two {

  @XmlElement
  private int a;
  @XmlElement
  private int b;

  public int getA() {return a;}
  public void setA(int a) {this.a = a;}
  public int getB() {return b;}
  public void setB(int b) {this.b = b}
}

b属性也是如此。然后,注释掉所有的getter和setter,并将成员公开,以便可以直接访问它们,结果与之前相同——生成的类2没有成员。当我将@XmlElement注释移动到getA()和getB()方法前面时也会发生同样的情况:deploy ok,WSDL包含a,b,但生成的两个不包含。有什么想法吗?还有什么可以尝试的吗?

jax-ws在引擎盖下使用jaxb来生成模式

因此,类必须符合jaxb,才能生成有效的complextype

对你们两个来说,这很简单:

@XmlAccessorType(XmlAccessType.PROPERTY)
@XmlRootElement(name="Two")
public class Two {
//
}

修改后,您现在面临的问题与数据类型上的
@xmlacessortype
注释(或缺少注释)有关。注释确定JAXB将如何访问,从而能够映射定义类型上的字段。注释提供了由注释定义的四个选项:
字段
属性
公共成员

默认值为
PUBLIC\u MEMBER
,这对JAXB意味着:映射所有非静态、非瞬态字段和所有javabean标准属性类型(即
getXXX
setXXX
对)。因为你有两个
inta
getA()
,相当于有两个同名的字段-
a

现在需要做的是定义一个
XmlAccessorType
,以消除混淆:

package uowsapp;

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


/**
 * <p>Java class for two complex type.
 * 
 * <p>The following schema fragment specifies the expected content contained within this class.
 * 
 * <pre>
 * &lt;complexType name="two">
 *   &lt;complexContent>
 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       &lt;sequence>
 *         &lt;element name="a" type="{http://www.w3.org/2001/XMLSchema}int"/>
 *         &lt;element name="b" type="{http://www.w3.org/2001/XMLSchema}int"/>
 *       &lt;/sequence>
 *     &lt;/restriction>
 *   &lt;/complexContent>
 * &lt;/complexType>
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "two", propOrder = {
    "a",
    "b"
})
public class Two {

    protected int a;
    protected int b;

    /**
     * Gets the value of the a property.
     * 
     */
    public int getA() {
        return a;
    }

    /**
     * Sets the value of the a property.
     * 
     */
    public void setA(int value) {
        this.a = value;
    }

    /**
     * Gets the value of the b property.
     * 
     */
    public int getB() {
        return b;
    }

    /**
     * Sets the value of the b property.
     * 
     */
    public void setB(int value) {
        this.b = value;
    }

}

我在这里选择了
属性
,因为它更符合Javabeans约定,但它也带来了其他优势,如中所述(假设这些优势并不真正适用于您的用例)

代码是正确的,不需要@XMLRootElement注释,也不需要@XmlElement注释

NetBeans没有生成具有字段和访问器的适当的类2的唯一原因是它使用的是WSDL的旧副本。我没有意识到Clean&Build——即使它删除了旧生成的源代码并重新生成它——并没有下载当前版本的WSDL。它总是使用我第一次尝试时使用的旧版本的WSDL,其中不包括字段a和b。要重新下载WSDL,请在项目浏览器中打开项目-打开“Web服务引用”项,右键单击特定的Web服务引用(在本例中为UserObj),然后说刷新。。。并在接下来的对话框中勾选“也是WSDL…”复选框

通过刷新WSDL,不带JAXB注释的原始版本和带JAXB注释的版本都运行良好,并生成了完整的第二类:

软件包uowsapp;
导入javax.xml.bind.annotation.XmlAccessType;
导入javax.xml.bind.annotation.XmlAccessorType;
导入javax.xml.bind.annotation.XmlType;
/**
*两个复杂类型的Java类。
* 
*以下架构片段指定此类中包含的预期内容。
* 
* 
*complexType name=“两个”>
*complexContent>
*限制基数=”{http://www.w3.org/2001/XMLSchema}任何类型“>
*序列>
*元素名称=“a”类型=”{http://www.w3.org/2001/XMLSchema}int“/>
*元素名称=“b”类型=”{http://www.w3.org/2001/XMLSchema}int“/>
*/顺序>
*/限制>
*/complexContent>
*/complexType>
* 
* 
* 
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name=“two”,比例={
“a”,
“b”
})
公共二班{
受保护的INTA;
受保护的int b;
/**
*获取属性的值。
* 
*/
公共int getA(){
返回a;
}
/**
*设置属性的值。
* 
*/
公共void setA(int值){
这个.a=值;
}
/**
*获取b属性的值。
* 
*/
公共int getB(){
返回b;
}
/**
*设置b属性的值。
* 
*/
公共无效收进(整数值){
这个.b=值;
}
}

非常感谢您的提示,我一直在怀疑这样的事情,但这会导致部署过程中出现异常-我已经编辑了上面的问题(根据建议…),非常感谢!现在,我了解了如何使用JAXB注释部署该类。但我仍然无法生成正确的第二类。看着NetBeans使用的WSDL的本地副本,我不明白为什么它与网络上的不同。事实证明,问题更简单——看我的答案。
package uowsapp;

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


/**
 * <p>Java class for two complex type.
 * 
 * <p>The following schema fragment specifies the expected content contained within this class.
 * 
 * <pre>
 * &lt;complexType name="two">
 *   &lt;complexContent>
 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       &lt;sequence>
 *         &lt;element name="a" type="{http://www.w3.org/2001/XMLSchema}int"/>
 *         &lt;element name="b" type="{http://www.w3.org/2001/XMLSchema}int"/>
 *       &lt;/sequence>
 *     &lt;/restriction>
 *   &lt;/complexContent>
 * &lt;/complexType>
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "two", propOrder = {
    "a",
    "b"
})
public class Two {

    protected int a;
    protected int b;

    /**
     * Gets the value of the a property.
     * 
     */
    public int getA() {
        return a;
    }

    /**
     * Sets the value of the a property.
     * 
     */
    public void setA(int value) {
        this.a = value;
    }

    /**
     * Gets the value of the b property.
     * 
     */
    public int getB() {
        return b;
    }

    /**
     * Sets the value of the b property.
     * 
     */
    public void setB(int value) {
        this.b = value;
    }

}