JAXB“在这个上下文中也不知道它的任何超类”避免@XmlSeeAlso

Posted

技术标签:

【中文标题】JAXB“在这个上下文中也不知道它的任何超类”避免@XmlSeeAlso【英文标题】:JAXB "nor any of its super class is known to this context" avoid @XmlSeeAlso 【发布时间】:2014-10-14 04:07:26 【问题描述】:

说明和解决方法

目前我正在使用 JAX-RS 并让 JAXB 绑定自动处理在 JEE6 项目中将数据转换为 XML 和 JSON。在我尝试创建一个通用响应对象来包装我的所有信息之前,一切都运行得非常好。

当我尝试使用我的通用响应类 com.eln00b.Wrapper(其中包含 private Object result 属性)时,我得到:

javax.xml.bind.MarshalException - 带有链接异常:[com.sun.istack.SAXException2: com.eln00b.CustomObject 类或其任何超类在此上下文中是已知的。 javax.xml.bind.JAXBException: com.eln00b.CustomObject 类或其任何超类在此上下文中都是已知的。]

所以我添加到com.eln00b.Wrapper:

@XmlSeeAlso (com.eln00b.CustomObject)
public class Wrapper 

一切正常。

问题

我希望这是非常通用的。我不想在com.eln00b.Wrapper 类的@XmlSeeAlso 注释中不断添加类。 如何让系统自动为 JAXB 上下文定位我的所有类?

即使是我使用Reflections 之类的东西来加载数据的黑客行为,也没关系。我只是不确定如何在没有 @XmlSeeAlso 注释的情况下获取上下文以加载所有这些数据。由于我将创建大量注释,它根本不起作用。

它是如何手动工作的

只需像手动转换一样添加数据,它就可以手动工作。但是,我确实想要使用手动 XML/JSON 创建,除非我绝对需要(我不想处理内容协商或类似的事情)。

示例:

JAXBContext.newInstance(new Class[] Wrapper.class, CustomObject.class);

【问题讨论】:

包罗万象的技术是从一个冒号分隔的包列表中创建 JAXBContext,一个或多个可以包含所有这些类。显然,必须为上下文创建提供一些提示 - 否则膨胀宇宙的边界将成为极限;-) @laune 这很好,但是我如何告诉 EE6 容器使用哪个JAXBContext?是否就像创建@Provider 一样简单? 我在 JAX-RS 文档中找到了这一点:“但是,如果默认的 JAXBContext 类不合适,那么您可以使用 JAX-RS ContextResolver 提供程序接口为应用程序提供 JAXBContext 类。”我必须深入挖掘你可能比我知道的更多才能更接近。对不起。 @laune 我在文档中没有看到。我得调查一下,看看是怎么回事。当我让它工作时(或者如果没有),我会在这里发布结果。 部分:“将 JAX-RS 与 JAXB 一起使用”docs.oracle.com/javaee/6/tutorial/doc/gkknj.html 【参考方案1】:

这就是自定义解析器的本质:

@Provider
@Produces (MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON)
public class JaxbContextResolver implements ContextResolver<JAXBContext> 

  @Override
  public JAXBContext getContext(Class<?> type) 
    // load appropriate context data
    Class[] bindTypes = ...

    // create 
    try 
      return JAXBContext.newInstance(bindTypes);
     catch (JAXBException e) 
      // todo:  this can be handled better but works for the example
      throw new RuntimeException(e);
    
  

现在,“加载适当的上下文数据”的处理非常简单。通过使用运行时数据基本上模仿@XmlSeeAlso

    创建将特定字段/方法标记为“上下文”的自定义内容(注释、处理方法等) 加载提取数据类型的字段/方法数据 确保不加载重复项并检查无限递归的可能性

现在,我使用了一些缓存来帮助提高自己的效率。我还为我的根对象创建了一个稍微复杂的设置,它实际上自己跟踪类数据并使其非常快速。我还创建了一个替代方案,将类标记为“上下文”,我使用包检查通过注释加载并自动添加到上下文中,但我还没有检查效率。我对第三次实施有一些想法,但我想完成更多的基准测试。

【讨论】:

如果你加载重复就可以了,jaxbContext 只会保存一次引用。确保 getContext 方法只被调用一次,这是一个非常昂贵的操作。记录警告消息或其他内容 @cocorossello 这实际上正是我所做的。最初的运行我只是让它被多次调用并且(虽然昂贵)并不可怕。当我进行负载测试时,它变得很明显。之后我切换了处理并确保它只被调用一次。一切都表现得非常好。

以上是关于JAXB“在这个上下文中也不知道它的任何超类”避免@XmlSeeAlso的主要内容,如果未能解决你的问题,请参考以下文章

Jaxb编组原始类型

什么是.episode文件..?

JAXB学习: 对JAXB支持的主要注解的说明

JAXB - The JAXB Context

JAXB - 属性“值”已定义。使用 <jaxb:property> 解决此冲突

JAXB简单样例