【问题标题】:Java Object to xml schema custom mapping - Web ServiceJava 对象到 xml 模式自定义映射 - Web 服务
【发布时间】:2017-11-01 20:12:40
【问题描述】:

我在 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。 Location - 要包含 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 类中的“customerType”属性可以有 3 个值('B','C','S')

所以,
例如,如果 customerType 的 runTime 值为“S”。

然后代码将分别在 SOAP 响应 XML 中生成 Location 对象属性为 'ShipperAddress1', 'ShipperAddress2', 'ShipperCity', 'ShipperState', 'ShipperZip', 'ShipperCountry' for 'address1' , 'address2', 'city', 'state', 'zip' and 'country'properties。

示例 2:如果 customerType 的 runTime 值为 'C'。

然后代码将分别在 SOAP 响应 XML 中生成 Location 对象属性为 'ConsigneeAddress1', 'ConsigneeAddress2', 'ConsigneeCity', 'ConsigneeState', 'ConsigneeZip', 'ConsigneeCountry' for 'address1' , 'address2', 'city', 'state', 'zip' and 'country' 属性。

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

【问题讨论】:

    标签: java xml jaxb marshalling


    【解决方案1】:

    您可以很好地做到这一点,使用@XmlElementRef,然后使用“位置继承”。

    拥有LocationAbstractLocation 的基类,然后为客户类型发货人或收货人“创建”位置实例,并覆盖子类中的元素名称。我在下面有一个示例来演示我在一个字段Address1 中显示它的位置。您可以类似地覆盖所有必填字段。

    请注意,我没有使用Field 访问类型,而是将其设置为Property,以便我们仅覆盖基类中保留"private" 的方法和字段。如果您认为字段可以是 protected.,您也可以调整它。

    示例

    在示例中,我刚刚使用了 LocationC​​trong> 和 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();
        }
    }
    

    【讨论】:

    • 非常感谢@Optional。此外,我正在查看 XML 注释,并且 '@XMLElelment' 和 '@XMLTransient' 为我工作。因此,我将“@XMLTransient”放在了 Shipper/Consignee/BillTo 的 getter 上。 {所有这些 S、C、B 都是 'Customer' 类中的 'Customer' 的数据类型} 并为所需属性添加了一些 getter 并将 getter 标记为 'XMLElelment'。我为“ShipperAddress1”指定它
    • XML Annotation(@) XmlRootElement XmlAccessorType(XmlAccessType.PROPERTY) 公共类 RatingProInfo 实现 Serializable { private int billDate; XmlTransient 私人客户托运人; XmlTransient 私人客户收货人; XmlTransient 私人客户 billTo; public RatingProInfo() { // web 服务需要这个 } XmlElement public Long getBillToAccountNumber() { return getBillTo().getAccountNumber(); } XmlElement public String getBillToAddress1() { return billTo.getLocation().getAddress1(); }
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-26
    • 2018-02-23
    • 2022-01-08
    • 1970-01-01
    • 2015-08-27
    • 2011-08-12
    • 1970-01-01
    相关资源
    最近更新 更多