无法从JAXB中发现QNAme的类:java.util.Map

时间:2014-02-07 16:05:03

标签: java xml spring-mvc jaxb wadl

我正在尝试使用 Spring Wadl Generator https://github.com/autentia/wadl-tools

AFAIK,这个工具使用Tomasz Nurkiewicz @ tomasz-nurkiewicz的相同想法:从Spring获取RequestMappingHandlerMapping,检查每个元素并生成一个合适的WADL。

在内部,该工具将使用JAXB在控制器中创建参数的XML。尽管很好,但事情并没有很好地适用于我的应用程序。

我遇到以下异常:

2014-02-07 15:33:41,827 WARN  user=unauthenticatedUser com.autentia.xml.namespace.QNameBuilder  - Cannot discover QName from JAXB annotations for class: java.util.Map. Preparing generic QName.com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
java.util.Map is an interface, and JAXB can't handle interfaces.
    this problem is related to the following location:
        at java.util.Map

来自(简化的堆栈跟踪)

at com.sun.xml.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:106)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:471)
    (...)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:248)
    (...)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:584)
at com.autentia.xml.namespace.QNameBuilder.discoverQNameFromJaxb(QNameBuilder.java:68)
    (...)
at com.autentia.web.rest.wadl.builder.ApplicationBuilder.build(ApplicationBuilder.java:36)

问题

我可以强制将默认适配器强制接口吗?

通常人们可以只为特定适配器的接口添加注释,但我不想更改和/或分析数百个类。

相关链接

被修改

不幸的是我无法更改REST API。

来自javadoc of MessageWriter

  

支持将Java类型转换为流的提供程序的合同。要添加MessageBodyWriter实现,请使用@Provider注释实现类。

WADL应该按原样提供服务信息。例如,通过注释添加MessageBodyWriter会更改API。既然我可以更改QNameBuilder.discoverQNameFromJaxb,那么在这个非常“瞬间”的MessageBodyWriter可能会更改/提供给java.util.Map并更改回WADL生成吗?

1 个答案:

答案 0 :(得分:3)

导致问题的原因

JAXB(JSR-222)实现可以将java.util.Map作为映射字段/属性处理,但不能将其作为根级别对象处理。您可能有一个与返回的RESTful操作相对应的方法需要Map

如何解决

  1. 您可以引入一个新的域对象,而不是将Map作为根级别对象,该对象具有类型为Map的映射字段/属性,而是使用它。
  2. MessageBodyReader类实现MessageBodyWriter / Map,以便使用它而不是使用JAXB。

  3. 更新

      

    我不想改变和分析数百个课程

    你不会。您只需添加一个MessageBodyReader / MessageBodyWriter来识别Map类(对于“application / xml”媒体类型)以对其进行特殊处理。另一种方法是继续获得例外。

      

    基本上我无法更改REST API。

    您不会更改REST API。您需要确保MessageBodyReader / MessaggeBodyWriter正常工作。

      

    通过使用低级别的暗魔法,可以提供一个   用于Map的MessageBodyWriter并在之后删除?

    这不是真正的低级别或黑暗魔法。您可以仅为Map类提供特殊处理。