Resteasy JAXB上下文没有拿起我的ObjectFactory

时间:2013-11-05 18:11:03

标签: jboss jaxb jboss7.x resteasy jaxb2

我在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模块很古老)。

2 个答案:

答案 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注释类。