Java对象到xml架构自定义映射 - Web服务

时间:2017-11-01 20:12:41

标签: java xml jaxb marshalling

我在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'属性。

我需要知道是否可以这样做,如果是,那么如何? 非常感谢所有的帮助。

1 个答案:

答案 0 :(得分:1)

你可以很好地做到这一点,使用@XmlElementRef,然后使用“遗产的位置。

拥有LocationAbstractLocation的基类,然后“创建”客户类型托运人或收货人的位置实例,并覆盖子类中的元素名称。我在下面有一个示例来演示我在一个字段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();
    }
}