无法使用 XStream Java lib 将属性绑定到对象

发布于 2024-11-04 18:00:53 字数 4110 浏览 7 评论 0原文

我在使用 XStream 将 xml 解组到对象时遇到问题。在我的 ImportItem 对象中,操作的属性值从未设置为字段操作。对于包含属性的其他元素,我使用自定义转换器,但我不想对人员使用客户转换器。这可能吗?我应该如何将操作绑定到 Item 对象?

XML:

<persons>
    <person operation="insert">
       <personNumber>196211065104</personNumber>
       <startDate>2011-04-13T00:00:00.000+02:00</startDate
       <expireDate>2012-04-14T00:00:00.000+02:00</expireDate
       <orderDate>2011-04-12T00:00:00.000+02:00</orderDate>
       <contact type="name">Joe</name>
       <contact type="email">[email protected]</contact>
       <contact type="landLine">12345678</contact>
    </person>
</persons>

我的工厂如下所示:

public class XStreamFactory {
    public static XStream instace() {
        XStream xs = new XStream();
        xs.aliasType("person", ImportItem.class);
        xs.useAttributeFor(ImportItem.class, "operation"); <-------
        xs.aliasType("persons", ImportBatch.class);
        xs.aliasType("contact", ImportContactData.class);


        xs.registerConverter(new ImportContactConverter());
        xs.registerConverter(new DateConverter());
        xs.registerConverter(new ImportOperationConverter()); <-------

        xs.addImplicitCollection(ImportBatch.class, "items");
        xs.addImplicitCollection(ImportItem.class, "contactData", ImportContactData.class);

        return xs;
    }

}

Batch:

@SuppressWarnings({"UnusedDeclaration"})
public class ImportBatch {

    private List<ImportItem> items;

    public List<ImportItem> getItems() {
        return items;
    }

    @Override
    public String toString() {
        return "ImportBatch{" +
               "items=\n  " + StringUtils.join(items, "\n  ") +
               "\n}";
    }
}

ImportItem:

@SuppressWarnings({"UnusedDeclaration"})
public class ImportItem {

    private ImportOperation operation;
    private String personNumber;
    private Date startDate;
    private Date expireDate;
    private Date orderDate;
    private List<ImportContactData> contactData;

    public ImportOperation getOperation() {
        return operation;
    }

    public void setOperation(ImportOperation operation) {
        this.operation = operation;
    }

    public String getCompanyName() {
        return companyName;
    }

    public String getOrganisationNumber() {
        return organisationNumber;
    }

    public String getItescoID() {
        return itescoID;
    }

    public String getAdID() {
        return adID;
    }

    public Date getStartDate() {
        return startDate;
    }

    public Date getExpireDate() {
        return expireDate;
    }

    public String getContactEmail() {
        return contactDataFor(email);
    }

    public String getContactPerson() {
        return contactDataFor(businessPerson);
    }

    public String getContactPhone() {
        return contactDataFor(landLine);
    }        
}

新的 ImportOperation 代码:<------

public class ImportOperation {

    public enum OperationType{insert, update, delete}

    private OperationType operation;

    public ImportOperation(OperationType operation) {
        this.operation = operation;
    }

    public OperationType getOperation() {
        return operation;
    }

    public void setOperation(OperationType operation) {
        this.operation = operation;
    }


}

新的转换器代码:<------

public class ImportOperationConverter implements SingleValueConverter {

    public String toString(Object obj) {
        return ((ImportOperation)obj).getOperation().toString();
    }

    public Object fromString(String str) {
        return new ImportOperation(ImportOperation.OperationType.valueOf(str));
    }

    public boolean canConvert(Class clazz) {
        return clazz == ImportOperation.class;
    }
}

I'm having trouble in unmarshalling xml with XStream to an Object. The attribute value for operation is never set to field operation in my ImportItem object. For my other elements that contain attributes I use custom converters but I would prefer not to use a customer converter for person. Is this possible and how should I do it to bind operation to the Item object?

XML:

<persons>
    <person operation="insert">
       <personNumber>196211065104</personNumber>
       <startDate>2011-04-13T00:00:00.000+02:00</startDate
       <expireDate>2012-04-14T00:00:00.000+02:00</expireDate
       <orderDate>2011-04-12T00:00:00.000+02:00</orderDate>
       <contact type="name">Joe</name>
       <contact type="email">[email protected]</contact>
       <contact type="landLine">12345678</contact>
    </person>
</persons>

My factory looks like this:

public class XStreamFactory {
    public static XStream instace() {
        XStream xs = new XStream();
        xs.aliasType("person", ImportItem.class);
        xs.useAttributeFor(ImportItem.class, "operation"); <-------
        xs.aliasType("persons", ImportBatch.class);
        xs.aliasType("contact", ImportContactData.class);


        xs.registerConverter(new ImportContactConverter());
        xs.registerConverter(new DateConverter());
        xs.registerConverter(new ImportOperationConverter()); <-------

        xs.addImplicitCollection(ImportBatch.class, "items");
        xs.addImplicitCollection(ImportItem.class, "contactData", ImportContactData.class);

        return xs;
    }

}

Batch:

@SuppressWarnings({"UnusedDeclaration"})
public class ImportBatch {

    private List<ImportItem> items;

    public List<ImportItem> getItems() {
        return items;
    }

    @Override
    public String toString() {
        return "ImportBatch{" +
               "items=\n  " + StringUtils.join(items, "\n  ") +
               "\n}";
    }
}

ImportItem:

@SuppressWarnings({"UnusedDeclaration"})
public class ImportItem {

    private ImportOperation operation;
    private String personNumber;
    private Date startDate;
    private Date expireDate;
    private Date orderDate;
    private List<ImportContactData> contactData;

    public ImportOperation getOperation() {
        return operation;
    }

    public void setOperation(ImportOperation operation) {
        this.operation = operation;
    }

    public String getCompanyName() {
        return companyName;
    }

    public String getOrganisationNumber() {
        return organisationNumber;
    }

    public String getItescoID() {
        return itescoID;
    }

    public String getAdID() {
        return adID;
    }

    public Date getStartDate() {
        return startDate;
    }

    public Date getExpireDate() {
        return expireDate;
    }

    public String getContactEmail() {
        return contactDataFor(email);
    }

    public String getContactPerson() {
        return contactDataFor(businessPerson);
    }

    public String getContactPhone() {
        return contactDataFor(landLine);
    }        
}

New ImportOperation code: <------

public class ImportOperation {

    public enum OperationType{insert, update, delete}

    private OperationType operation;

    public ImportOperation(OperationType operation) {
        this.operation = operation;
    }

    public OperationType getOperation() {
        return operation;
    }

    public void setOperation(OperationType operation) {
        this.operation = operation;
    }


}

New converter code: <------

public class ImportOperationConverter implements SingleValueConverter {

    public String toString(Object obj) {
        return ((ImportOperation)obj).getOperation().toString();
    }

    public Object fromString(String str) {
        return new ImportOperation(ImportOperation.OperationType.valueOf(str));
    }

    public boolean canConvert(Class clazz) {
        return clazz == ImportOperation.class;
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

朮生 2024-11-11 18:00:53

您需要告诉XStream该字段操作是一个xml属性。

添加

xs.useAttributeFor(ImportItem.class, "operation");

@see XStream 别名教程

原因是,XStream 默认情况下将所有内容映射到 XML 字段。如果您解组对象并且 XML 中未定义对象字段,则 XStream 默认情况下会将其设置为 NULL。 -- 将这两部分放在一起解释行为,并告诉您该怎么做。 ->配置映射,以便将 Person.operation 映射到属性。

You need to tell XStream that the field operation is an xml attribute.

add

xs.useAttributeFor(ImportItem.class, "operation");

@see XStream Alias Tutorial

The reason is, that XStream map everything to XML fields by default. If you unmarshalling an object and an Object field is not defined in the XML then XStream will set it to NULL by default. -- Putting this two pieces together explain the behaviour, and tell you what to do. -> Configure the mapping so that the Person.operation is mapped to the attribute.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文