I'm getting an XStream error with the following setup. I must be crazy. What's wrong?
The request class
@XStreamAlias("RequestTO")
public class RequestTO {
@XStreamImplicit
private List<SkuMerchTO> skuNumbers;
...
}
The nested object class
@XStreamAlias("skuMerch")
public class SkuMerchTO {
@XStreamAlias("skuNumber")
@XStreamAsAttribute
private Integer skuNumber;
@XStreamAlias("dept")
@XStreamAsAttribute
private Short department;
@XStreamAlias("class")
@XStreamAsAttribute
private Short cls;
@XStreamAlias("subClass")
@XStreamAsAttribute
private Short subClass;
...
}
XStream code to decode the XML to an object:
XStream stream = new XStream();
stream.processAnnotations(SkuMerchTO.class);
stream.processAnnotations(RequestTO.class);
RequestTO request = (RequestTO)stream.fromXML(requestXml);
XML input string:
<RequestTO>
<skuMerch skuNumber="123456" dept="1" class="2" subClass="3"/>
<skuMerch skuNumber="234567" dept="4" class="5" subClass="6"/>
</RequestTO>
Error in Stacktrace:
---- Debugging information ----
message : 2 : 2
cause-exception : com.thoughtworks.xstream.mapper.CannotResolveClassException
cause-message : 2 : 2
class : [...]RequestTO
required-type : [...]SkuMerchTO
path : /RequestTO/skuNumberList/skuMerch
line number : 3
.-------------------------------
com.thoughtworks.xstream.converters.ConversionException: 2 : 2 : 2 : 2
---- Debugging information ----
message : 2 : 2
cause-exception : com.thoughtworks.xstream.mapper.CannotResolveClassException
cause-message : 2 : 2
class : [...]RequestTO
required-type :[..]SkuMerchTO
path : /RequestTO/skuNumberList/skuMerch
line number : 3
.-------------------------------
If I create the objects and do toXML I get this:
<RequestTO>
<skuMerch skuNumber="0" dept="1" class="2" subClass="2"/>
<skuMerch skuNumber="1" dept="1" class="2" subClass="2"/>
<skuMerch skuNumber="2" dept="1" class="2" subClass="2"/>
</RequestTO>
EDIT: The hilarious thing is, if do this:
stream.fromXML(stream.toXML(object));
It still fails on the from XML part!
The attribute named class
has a special meaning to XStream, this question suggests that you can tell XStream to use a different attribute for this purpose via something like
stream.aliasSystemAttribute("__class", "class");
This would cause XStream to use __class
as the "special" attribute, and treat class
as a normal one. Or, if you know you don't need the XStream magic handling of class
for any of your objects you can say
stream.aliasSystemAttribute(null, "class");
to tell it not to use this feature at all.
You may also need to use itemFieldName="skuMerch"
on the @XStreamImplicit
annotation, as per the XStream annotation tutorial.