我最近在我的Eclipse中启动了我的WebServicesExplorer,我才意识到JAXB生成的xs:element
名称并不那么冗长。以下是其中一个序列:
<xs:sequence>
<xs:element minOccurs="0" name="arg0" type="xs:string" />
<xs:element minOccurs="0" name="arg1" type="xs:string" />
<xs:element name="arg2" type="xs:int" />
</xs:sequence>
从此文件生成:
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class User {
private String firstName;
private String lastName;
private int age;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
我还不是JAXB专家,所以我想知道我是否可以将这些arg *命名元素更改为合理的东西,比如在POJO类中?
答案 0 :(得分:1)
您没有提到您正在使用的Web服务框架,但行为听起来类似于JAX-WS规范,例如: The parts in my generated wsdl have names of the form "arg0", "arg1", ... Why don't the parts (and Java generated from them) use the nice parameter names I typed into the interface definition?
官方回答: JAX-WS规范(特别是第3.6.1节)要求以这种方式生成它。要自定义名称,必须使用@WebParam(name =“blah”)注释来指定更好的名称。 (您可以使用@WebResult作为返回值,但只有在查看XML时才会看到结果。)
原因: java的一个谜团是,即使使用调试信息,抽象方法(以及接口方法)也不会将其参数名称编译到其中。因此,当从接口构建服务模型时,无法确定原始代码中使用的名称。
如果服务是从具体类(而不是接口)构建的,并且该类是使用调试信息编译的,那么我们可以获取参数名称。简单的前端就是这样做的。但是,这可能会导致潜在的问题。例如,当你从开发到生产时,你可以关闭调试信息(从javac标志中删除-g),然后突然应用程序可能会破坏,因为生成的wsdl(因此期望soap消息)会改变。因此,JAX-WS规范编写者走了安全路线并要求您必须使用@WebParam注释来指定更具描述性的名称。
您可以尝试为每个字段添加XmlElement注释并指定名称,但是您确定这是由JAXB引起的吗?如果我使用您的POJO代码运行schemagen,这就是我得到的(名称被正确选取):
<xs:complexType name="user">
<xs:sequence>
<xs:element name="age" type="xs:int"/>
<xs:element name="firstName" type="xs:string" minOccurs="0"/>
<xs:element name="lastName" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
根据您的评论,如果您将POJO“强制”为以下代码,您是否仍会收到有关重复名称的投诉?
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlAccessType;
@XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement
public class User {
@XmlElement(name = "firstName")
private String firstName;
@XmlElement(name = "lastName")
private String lastName;
@XmlElement(name = "age")
private int age;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}