一、现象描述:
用JAXB转XML时报错,该对象有一个List<Staff>属性。报错如下:
javax.xml.bind.JAXBException: class com.me.domain.Staff nor any of its super class is known to this context.]
StaffQryResponse类:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name="staffQryResponse")
public class StaffQryResponse extends BaseResponse {
@XmlAttribute
private long total;
@XmlElement(name="staff")
private List<Staff> staffs;
...
}
Staff类:
XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name="staff")
public class Staff implements Serializable {
private static final long serialVersionUID = 1L;
@XmlAttribute
private String staffId;
@XmlElement
private String staffCode;
@XmlElement
private String staffName;
...
}
二、问题分析:
奇怪的时自己做测试时是正常的,但框架运行的时候报错。分析差别,在于自己测试时List<Staff>是自己创建的,如下所示:
StaffQryResponse response = new StaffQryResponse();
List<Staff> staffs = new ArrayList<Staff>();
...
response.setStaffs(staffs);
但框架运行时, List是由MyBatis创建的。看Mybatis源码,最终List是 new ArrayList<Object>() 这样来创建的。
所以JAXB在运行时,认为元素是Object,没有@XmlRootElement注解,不知道如何处理,所以失败.
三、解决方法:
1. List在创建时类似 List<Staff> staffs = new ArrayList<Staff>() 这样来创建。
2. 在List的@XmlElement注释里,指明元素数据类型。
@XmlElement(name="staff",type=Staff.class)
private List<Staff> staffs;
希望能帮助同样遇到该问题的朋友。