客户端在某些代码上运行java2ws时遇到问题,这些代码使用&扩展从我的SOAP Web服务中消耗的类。困惑了吗? :)
我正在公开SOAP Web服务(JBoss5,Java 6)。有人正在使用Axis1使用该Web服务,并使用数据类型和客户端存根创建一个jar。然后他们定义自己的类型,这扩展了我的一种类型。我的类型包含枚举。
class MyParent {
private MyEnumType myEnum;
// getters, settters for myEnum;
}
class TheirChild extends MyParent {
...
}
当他们在代码上运行java2ws(扩展我的类)时,他们会得到
Caused by: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions
net.foo.bar.MyEnuMType does not have a no-arg default constructor.
this problem is related to the following location:
at net.foo.bar.MyEnumType
at public net.foo.bar.MyEnumType net.foo.bar.MyParent.getMyEnum()
我定义的枚举如下。这是现在它被消费后的结果,但它是我在应用服务器上定义它的方式:
@XmlType(name = "MyEnumType")
@XmlEnum
public enum MyEnumType {
Val1("Val1"),
Val2("Val2")
private final String value;
MyEnumType(String v) {
value = v;
}
public String value() {
return value;
}
public static MyEnumType fromValue(String v) {
if (v == null || v.length() == 0) {
return null;
}
if (v.equals("Val1")) {
return MyEnumType.Val1;
}
if (v.equals("Val2")) {
return MyEnumType.Val2;
}
return null;
}
}
我在网上和其他帖子上看到了一些事情,比如(this one)关于Jaxb无法处理列表或类似的事情,但我对我的枚举感到困惑。我很确定你不能拥有一个枚举的默认构造函数(好吧,至少是一个公共的无参数构造函数,当我尝试时Java会对我大吼大叫),所以我不确定是什么原因导致这个错误成为可能。有什么想法吗?
此外,“IllegalAnnotationsExceptions的2个计数”可能是因为我的代码实际上有两个类似的枚举,但为了简洁起见,我将它们排除在此示例之外。
答案 0 :(得分:9)
JAXB的no-arg构造函数不必是public
,它可以是private
:
private String value;
private MyEnumType() {} // for JAXB
MyEnumType(String v) {
value = v;
}
但是,您不能以这种方式保留value
成员final
。
答案 1 :(得分:2)
我确信你可以拥有枚举的默认构造函数。 实际上,当你没有明确地定义构造函数时,你拥有的是什么 (和你的String参数一样)。
你也可以有几个构造函数,一个没有参数和其他构造函数。
在您给出的精确示例中,完全避免使用String参数会很简单。 提供的name()方法具有您提供的值。 代码甚至更简单:
@XmlType(name = "MyEnumType")
@XmlEnum
public enum MyEnumType {
Val1, Val2;
public String value() {
return name();
}
public static MyEnumType fromValue(String v) {
for(MyEnumType type : values()) {
if (type.value().equals(v)) {
return type;
}
}
return null;
}
}
如果您确实要为每个值设置一些复杂的参数,并且由于库而无法使用特定的构造函数,您还可以将不同的值存储到EnumMap中,并根据需要进行读取。
答案 2 :(得分:0)
当您从-java-to-wsdl执行时,apache检查首先是枚举类是否枚举,并且只有在此检查失败时才检查构造函数。您可以在org.apache.axis.wsdl.fromJava.Types :: isBeanCompatible中看到它。任何正常的男人,都会认为如果他写的话
public enum MyEnum{}
就足够了。但是Apache开发人员并不这么认为(IDK为什么,可能出于某些兼容性原因)。他们使用这个方法 - org.apache.axis.utils.JavaUtils :: isEnumClassSub。
如果你要解散这个课程,你会看到你的枚举