web.xml 中 Apache CXF 的 JSONProvider namespaceMap 配置

JSONProvider namespaceMap config in web.xml for Apache CXF

我需要通过 Apache CXF 中的 web.xml 文件将 namespaceMap 传递给 JSONProvider 配置。

我没有在这个应用程序上使用 Spring,也没有像这个问题建议的那样对 Providers 进行编程配置:CXF: No message body writer found for class - automatically mapping non-simple resources

而是使用 this non-Spring example from the CXF code 风格的配置。

但是,该示例并未显示如何提供 namespaceMap,而且我不确定如何在那种配置风格中指定地图。

我将继续进行一些反复试验。

有人知道 web.xml 配置的 JSONProvider 语法参考指南吗?

我找不到参考指南,但通过一些代码探索和 this mailing list thread from the archives.

设法解决了配置问题

出于某种原因,来自该邮件列表线程的建议不起作用(它忽略了来自 web.xml 的自定义 JSONProvider)。我可能遇到了其他问题。

最终,我放弃了 web.xml 配置的想法,因为它已经被用来提供 javax.ws.rs.Application 并且(从查看@CXF 代码来看),CXF 似乎忽略了 init-param 来自 web.xml 的元素,如果它找到一个应用程序。

此外,web.xml 配置中似乎没有表达地图类型的方法。那是根据跟帖和看代码的猜想,所以不能100%确认。

这是我的 web.xml 的样子(这些更改前后相同):

<servlet>
    <servlet-name>CXFServlet</servlet-name>
    <display-name>CXF Servlet</display-name>
    <servlet-class>org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet</servlet-class>
    <init-param>
        <param-name>javax.ws.rs.Application</param-name>
        <param-value>my.javax-ws-rs.Application</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

我需要在 my.javax-ws-rs.Application class 中进行更改。

简单地添加了一个新的 JSONProvider 到其中的单例列表:

@Override
public Set< Object> getSingletons() {
    final Set< Object> singletons = new HashSet<>();

   // [SNIP -- existing singletons]
    singletons.add( new my.provider.MyJSONProvider() );

    return singletons;
}

my.provider.MyJSONProvider 的定义是其余魔法发生的地方(是的,这是 "programmatic" 配置,我说我没有,但最终不得不求助于):

@Produces({MediaType.APPLICATION_JSON})
@Consumes({MediaType.APPLICATION_JSON}) 
@Provider
public class MyJSONProvider<T> extends JSONProvider<T> {

  public AdministrationUtilisatuerJSONProvider() {

    {
        Map<String, String> newNamespaceMap = new ConcurrentHashMap<>();

        XmlSchema resource1SchemaAnnotation = Resource1.class.getPackage().getAnnotation(javax.xml.bind.annotation.XmlSchema.class);
        String resource1Namespace = resource1SchemaAnnotation.namespace();
        newNamespaceMap.put( resource1Namespace, "resource1JsonPrefix" );

        XmlSchema resource2SchemaAnnotation = Resource2.class.getPackage().getAnnotation(javax.xml.bind.annotation.XmlSchema.class);
        String resource2Namespace = resource2SchemaAnnotation.namespace();
        newNamespaceMap.put( resource2Namespace, "resource2JsonPrefix" );

        setNamespaceMap(newNamespaceMap);
    }

    // Or set this to "true" to ignore all that namespace stuff
    // setIgnoreNamespaces(true);

    // Don't write namespace for default xsi-type elements.
    setWriteXsiType(false);

    // [SNIP] -- Other JSONProvider configuration.  
    //           Check source from CXF, but few comments in code.

  }

关于让基于 Jettison 的 JSON 在 CXF 中工作的最后一点说明:您还需要 class 路径上的 cxf-rt-rs-extension-providers-X.Y.Z.jar。这在 CXF WHICH_JARS 文件中没有记录,但是是必需的。