我在JAX-WS中有一个Web服务,pom.xml中的maven目标('ws-jwsc')生成WSDL文件以及输入和输出XSD。
我想以不同的方式将java类的属性映射更改为WSDL / XSD架构,如下所示:
我有两个班级1)客户2)位置
1。客户 - 客户特定信息
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
public Customer() {
super();
}
public Customer(CustomerType customerType) {
this.customerType = customerType;
}
public enum CustomerType {
B, S, C
}
private CustomerType customerType;
private String name;
private Long accountNumber;
private Location location;
// getter/setter for properties
}
2。位置 - 包含addr1 / addr2 / city / state / zip / country
的位置对象@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Location {
private String address1;
private String address2;
private String city;
private String state;
private String zip;
private String country;
/**
* @return the city
*/`enter code here`
public String getCity() {
return city;
}
//getter/setter for properties
}
现在我的问题是在运行时,Customer类中可以有3个值('B','C','S')
的'customerType'属性
所以,
例如,如果customerType的runTime值为'S'。
然后代码将分别在SOAP响应XML中生成Location对象属性'ShipperAddress1', 'ShipperAddress2', 'ShipperCity', 'ShipperState', 'ShipperZip', 'ShipperCountry' for 'address1' , 'address2', 'city', 'state', 'zip' and 'country'
属性。
example2:如果customerType的runTime值为'C'。
然后代码将分别在SOAP响应XML中生成Location对象属性'ConsigneeAddress1', 'ConsigneeAddress2', 'ConsigneeCity', 'ConsigneeState', 'ConsigneeZip', 'ConsigneeCountry' for 'address1' , 'address2', 'city', 'state', 'zip' and 'country'
属性。
我需要知道是否可以这样做,如果是,那么如何? 非常感谢所有的帮助。
答案 0 :(得分:1)
你可以很好地做到这一点,使用@XmlElementRef
,然后使用“遗产的位置。
拥有Location
或AbstractLocation
的基类,然后“创建”客户类型托运人或收货人的位置实例,并覆盖子类中的元素名称。我在下面有一个示例来演示我在一个字段Address1
中显示它的位置。您可以类似地覆盖所有必填字段。
请注意,我没有使用Field
访问类型,而是将其设为Property
,以便我们只覆盖基类中的方法和字段"private"
。如果您认为字段可以是protected.
,那么您也可以对其进行调整。
示例
在示例中,我刚刚使用了 LocationC 和 LocationS 。您可以添加LocationB
。
主要类的Customer.java。注意@XmlElementRef(name =“Location”)
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
public CustomerType getCustomerType() {
return customerType;
}
public void setCustomerType(CustomerType customerType) {
this.customerType = customerType;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getAccountNumber() {
return accountNumber;
}
public void setAccountNumber(Long accountNumber) {
this.accountNumber = accountNumber;
}
public GeneralLocation getLocation() {
return location;
}
public void setLocation(GeneralLocation location) {
this.location = location;
}
public Customer() {
super();
}
public Customer(CustomerType customerType) {
this.customerType = customerType;
}
public enum CustomerType {
B, S, C
}
private CustomerType customerType;
private String name;
private Long accountNumber;
@XmlElementRef(name = "Location")
private GeneralLocation location;
public static void main(String[] args) throws Exception {
Customer c = new Customer();
c.setAccountNumber(1111111l);
c.setCustomerType(CustomerType.C);
LocationC loc = new LocationC();
loc.setAddress1("I am address 1");
c.setLocation(loc);
Customer c2 = new Customer();
c2.setAccountNumber(222222l);
c.setCustomerType(CustomerType.S);
LocationS locs = new LocationS();
locs.setAddress1("I am S address 1");
c2.setLocation(locs);
JAXBContext jc = JAXBContext.newInstance(Customer.class);
Marshaller marrshaller = jc.createMarshaller();
marrshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marrshaller.marshal(c, System.out);
marrshaller.marshal(c2, System.out);
}
}
Base AbstractLocation.java(我使用注释@XmlTransient隐藏了它的属性。
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.XmlTransient;
@XmlRootElement
@XmlAccessorType(XmlAccessType.PROPERTY)
@XmlSeeAlso({LocationC.class, LocationS.class})
abstract class GeneralLocation {
private String address1;
private String address2;
private String city;
private String state;
private String zip;
private String country;
@XmlTransient()
public String getAddress1() {
return address1;
}
public void setAddress1(String address1) {
this.address1 = address1;
}
public String getAddress2() {
return address2;
}
public void setAddress2(String address2) {
this.address2 = address2;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getZip() {
return zip;
}
public void setZip(String zip) {
this.zip = zip;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
}
LocationC.java
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement()
public class LocationC extends GeneralLocation {
@XmlElement(name="ConsigneeAddress1")
@Override
public String getAddress1() {
return super.getAddress1();
}
}
LocationS.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;
@XmlRootElement()
@XmlAccessorType(XmlAccessType.PROPERTY)
public class LocationS extends GeneralLocation {
@XmlElement(name="ShipperAddress1")
public String getAddress1() {
return super.getAddress1();
}
}