解释和解决方法
目前,我正在 JEE6 项目中使用 JAX-RS 并让 JAXB 绑定(bind)自动处理将数据转换为 XML 和 JSON。一切都工作得非常出色,直到我尝试创建一个通用响应对象来包装我的所有信息。
当我尝试使用通用响应类com.eln00b.Wrapper
(其中包含私有(private)对象结果
属性)时,我得到:
javax.xml.bind.MarshalException - with linked exception: [com.sun.istack.SAXException2: class com.eln00b.CustomObject nor any of its super class is known to this context. javax.xml.bind.JAXBException: class com.eln00b.CustomObject nor any of its super class is known to this context.]
所以我添加到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});
最佳答案
这就是自定义解析器的本质:
@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
:
- 创建自定义内容(注释、处理方法等),将特定字段/方法标记为“上下文”
- 加载字段/方法数据并提取数据类型
- 确保不加载重复项并检查无限递归的可能性
现在,我使用了一些缓存来帮助自己提高工作效率。我还为我的根对象创建了一个稍微复杂的设置,它实际上自己跟踪类数据并使其速度相当快。我还创建了一个替代方案,将类标记为“上下文”,我使用包检查通过注释加载并自动添加到上下文,但我尚未检查其效率。我对第三次实现有一些想法,但我希望完成更多基准测试。
关于java - JAXB "nor any of its super class is known to this context"避免@XmlSeeAlso,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25410831/