无法使用 XStream Java lib 将属性绑定到对象
我在使用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您需要告诉XStream该字段操作是一个xml属性。
添加
@see XStream 别名教程
原因是,XStream 默认情况下将所有内容映射到 XML 字段。如果您解组对象并且 XML 中未定义对象字段,则 XStream 默认情况下会将其设置为 NULL。 -- 将这两部分放在一起解释行为,并告诉您该怎么做。 ->配置映射,以便将 Person.operation 映射到属性。
You need to tell XStream that the field operation is an xml attribute.
add
@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.