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的主要内容,如果未能解决你的问题,请参考以下文章