说明&解决方案
目前我在JEE6项目中使用JAX-RS并让JAXB绑定自动处理将数据转换为XML和JSON。一切都运行得非常好,直到我尝试创建一个通用响应对象来封装我的所有信息。
当我试图使用我的通用响应类com.eln00b.Wrapper
(其中包含private Object result
属性)时,我得到:
javax.xml.bind。MarshalException -带有链接异常:[com.sun.istack.]SAXException2:类com.eln00b。此上下文不知道CustomObject及其任何超类。jaxbexcexception:类com.eln00b。CustomObject及其任何超类都不为此上下文所知。]
所以我添加到com.eln00b.Wrapper
:
@XmlSeeAlso ({com.eln00b.CustomObject})
public class Wrapper {
}
一切正常
<标题>我希望这是非常通用的。我不想不断地向com.eln00b.Wrapper
类上的@XmlSeeAlso
注释添加类。我如何让系统自动定位JAXB上下文的所有类?
即使它是一个hack,我使用一些像反射加载数据,这是好的。我只是不知道如何获得上下文加载所有这些数据没有@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
:
- 创建一个自定义的东西(注释、处理方法等),将特定的字段/方法标记为"上下文"
- 加载提取数据类型的字段/方法数据
- 确保不加载重复项并检查无限递归的可能性
现在,我使用一些缓存来帮助自己提高效率。我还为我的根对象创建了一个稍微复杂的设置,它实际上自己跟踪类数据,并使其非常快速。我还创建了一个替代方案,将类标记为"上下文",我使用包检查通过注释加载,并自动添加到上下文中,但我还没有检查其效率。我对第三个实现有一些想法,但我想完成更多的基准测试。