我在JBOSS 7.1下运行REST(Resteasy)客户端。从服务器返回的响应要求我使用自己的JAXB ObjectFactory,因为相同的Java类型被映射到多个XML元素:
@XmlRegistry
public class ObjectFactory {
private final static QName RESPONSE_QNAME = new QName("response");
private final static QName ORDER_QNAME = new QName("order");
@XmlElementDecl(name="response")
public JAXBElement<PurchaseResponse> getPurchaseResponse(PurchaseResponse r) {
return new JAXBElement<PurchaseResponse>(RESPONSE_QNAME, PurchaseResponse.class, null);
}
@XmlElementDecl(name="order")
public JAXBElement<PurchaseResponse> getOrderResponse(PurchaseResponse r) {
return new JAXBElement<PurchaseResponse>(ORDER_QNAME, PurchaseResponse.class, null);
}
我像这样建立了RestEasy客户端:
ResteasyClient client = new ResteasyClientBuilder().build();
ResteasyWebTarget httpTarget = client.target( endpoint );
RestService target = httpTarget.proxy(RestService.class);
Response resp = target.callAPI();
return resp.readEntity(PurchaseResponse.class);
其中RestService是表示REST API方法的接口。这项工作提供了PurchaseResponse类在类上有XmlRootElement注释。一旦我将其删除,readEntity()调用就会失败,并且无法找到邮件正文处理器&#39;。但是,我不希望JAXB在我的ObjectFactory中使用XmlRootElement注释但使用XmlElementDecl注释,并且它没有发生。
我可以通过为我的包显式构建JAXB上下文,手动将响应读入字符串,然后将其解析为XML文档并最终输入由上下文生成的JAXB unmarshaller(唉!)来使其工作。我每次打电话给API时都不想这样做。
为什么默认的JAXB unmarshaller不是拿起我的ObjectFactory类并使用它?我使用本地捆绑的RestEasy库(JBOSS提供的RestEasy模块很古老)。
答案 0 :(得分:1)
当JAXBContext
构建在一个或多个类上时,它不会自动拉入.l您可以创建ContextResolver
来控制JAXBContext
使用的JAX-RS
{1}}实施。
答案 1 :(得分:1)
在深入研究Resteasy资源后,在我看来,目标类必须使用XmlType进行注释,以便RE开始寻找ObjectFactory:
public abstract class AbstractJAXBContextFinder implements JAXBContextFinder
{
protected static final String OBJECT_FACTORY_NAME = ".ObjectFactory";
public static Class<?> findDefaultObjectFactoryClass(Class<?> type)
{
XmlType typeAnnotation = type.getAnnotation(XmlType.class);
if (typeAnnotation == null) return null;
if (!typeAnnotation.factoryClass().equals(XmlType.DEFAULT.class)) return null;
StringBuilder b = new StringBuilder(getPackageName(type));
b.append(OBJECT_FACTORY_NAME);
Class<?> factoryClass = null;
try
{
factoryClass = Thread.currentThread().getContextClassLoader().loadClass(b.toString());
}
catch (ClassNotFoundException e)
{
return null;
}
if (factoryClass.isAnnotationPresent(XmlRegistry.class)) return factoryClass;
return null;
}
}
我在类上添加了@XmlType注释,而RestEasy readEntity()调用现在正在解组。我仍然需要进行全面测试,但是现在我觉得这样可行。
看起来像Resteasy中的一个错误:对象工厂也应该加载@XmlRootElement注释类。