CXF JSONProvider编组导致java.lang.ClassNotFoundException:com.sun.xml.bind.marshaller.NamespacePrefixMapper

时间:2014-12-17 17:27:16

标签: java xml web-services jaxb cxf

我正在尝试使用 CXF 设置 JAX-RS 服务,该服务将接受并返回 json xml < / strong>即可。此外,我希望通过 JAXB 使用 xsd 验证请求消息。 为了达到这个目的,我已经解决了一些问题,但总会有另一个问题需要克服。

所以这个问题是关于

java.lang.ClassNotFoundException: com.sun.xml.bind.marshaller.NamespacePrefixMapper

我得到的配置和异常如下所示

的beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans namespaces....>
    <jaxrs:server address="/">
        <jaxrs:serviceBeans>
            <bean class="com.ba.sysman.services.events.IncidentService"></bean>
        </jaxrs:serviceBeans>
        <jaxrs:providers>
                <bean id="jaxbJSONProvider" class="org.apache.cxf.jaxrs.provider.json.JSONProvider">
                    <property name="namespaceMap" ref="jsonNamespaceMap"/>
                    <property name="schemaHandler" ref="schemaHolder"/>
                    <property name="serializeAsArray" value="true"/>
                    <property name="produceMediaTypes" ref="jsonTypes"/>
                    <property name="consumeMediaTypes" ref="jsonTypes"/>
                </bean>
                <bean id="jaxbProvider" class="org.apache.cxf.jaxrs.provider.JAXBElementProvider">
                    <property name="schemaHandler" ref="schemaHolder"></property>
                </bean>
        </jaxrs:providers>
        <jaxrs:features>
            <cxf:logging/>
        </jaxrs:features>
    </jaxrs:server>
    <bean id="schemaHolder" class="org.apache.cxf.jaxrs.utils.schemas.SchemaHandler">
        <property name="schemaLocations" ref="theSchemas"/>
    </bean>
    <util:list id="theSchemas">
        <value>../../xsd/incident.xsd</value>
    </util:list>
    <util:map id="jsonNamespaceMap" map-class="java.util.Hashtable">
        <entry key="http://www.ba.com/schema/BAserviceDeskAPI/incident" value=""/>
        <entry key="http://www.ba.com/schema/BAserviceDeskAPI" value=""/>
    </util:map>
    <util:list id="jsonTypes">
        <value>application/json</value>
        <value>application/x-javascript</value>
        <value>application/vnd.example-com.foo+json</value>
    </util:list>
</beans>

我的服务

@Path("incident")
public class IncidentService {

    @POST
    @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
    @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
    public Response createIncident(Incident incident,
            @HeaderParam("Accept") String acceptHeader,
            @HeaderParam("skip-creation") boolean skip) {

        String responseType = null;
        if (acceptHeader.equals(MediaType.APPLICATION_XML)) {
            responseType = MediaType.APPLICATION_XML;
        } else {
            responseType = MediaType.APPLICATION_JSON;
        }
        IncidentServiceResponse response = getResponse();
        return Response.ok(response).type(responseType).build();    
    }
}

IncidentServiceResponse

package com.ba.sysman.assyst.rest.responses;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class IncidentServiceResponse {

    @XmlElement
    Integer ticketId;
    @XmlElement
    String errorMessage;
    @XmlTransient
    String rawResponse;
    public IncidentServiceResponse() {
        // TODO Auto-generated constructor stub
    }
    public IncidentServiceResponse(Integer id, String rawResponse) {
        this.ticketId = id;
        this.rawResponse = rawResponse;
    }
    public Integer getTicketId(){
        return ticketId;
    }
    public String getRawResponse() {
        return rawResponse;
    }
    public void setErrorMessage(String errorMessage) {
        this.errorMessage = errorMessage;
    }
    public String getErrorMessage() {
        return errorMessage;
    }
}

pacage-info.java用于IncidentServiceResponse

@XmlSchema(namespace = "http://www.ba.com/schema/BAserviceDeskAPI", elementFormDefault = XmlNsForm.QUALIFIED)
package com.ba.sysman.assyst.rest.responses;

import javax.xml.bind.annotation.XmlSchema;
import javax.xml.bind.annotation.XmlNsForm;

例外

org.apache.cxf.interceptor.Fault: com/sun/xml/bind/marshaller/NamespacePrefixMapper
    at org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.handleWriteException(JAXRSOutInterceptor.java:363)
    at org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.serializeMessage(JAXRSOutInterceptor.java:266)
    at org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.processResponse(JAXRSOutInterceptor.java:117)
    at org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.handleMessage(JAXRSOutInterceptor.java:80)
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
    at org.apache.cxf.interceptor.OutgoingChainInterceptor.handleMessage(OutgoingChainInterceptor.java:83)
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
    at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
    at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:243)
    at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:223)
    at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:197)
    at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:149)
    at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:171)
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:286)
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:206)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:262)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NoClassDefFoundError: com/sun/xml/bind/marshaller/NamespacePrefixMapper
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:2895)
    at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:1173)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1681)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1559)
    at org.apache.cxf.common.classloader.ClassLoaderUtils.loadClass(ClassLoaderUtils.java:256)
    at org.apache.cxf.common.jaxb.JAXBUtils.createNamespaceWrapper(JAXBUtils.java:1024)
    at org.apache.cxf.common.jaxb.JAXBUtils.setNamespaceMapper(JAXBUtils.java:559)
    at org.apache.cxf.jaxrs.provider.AbstractJAXBProvider.setNamespaceMapper(AbstractJAXBProvider.java:155)
    at org.apache.cxf.jaxrs.provider.json.JSONProvider.marshal(JSONProvider.java:499)
    at org.apache.cxf.jaxrs.provider.json.JSONProvider.marshal(JSONProvider.java:611)
    at org.apache.cxf.jaxrs.provider.json.JSONProvider.writeTo(JSONProvider.java:388)
    at org.apache.cxf.jaxrs.utils.JAXRSUtils.writeMessageBody(JAXRSUtils.java:1363)
    at org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.serializeMessage(JAXRSOutInterceptor.java:244)
    ... 31 more
Caused by: java.lang.ClassNotFoundException: com.sun.xml.bind.marshaller.NamespacePrefixMapper
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1714)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1559)
    ... 47 more

在我的请求中,我发送了一条JSON消息,该消息正在被解组并成功验证,因此我没有包含上面的突发事件对象。但是在回复中, IncidentServiceResponse 的解组失败,上面有例外。

我花了一整天寻找解决方案,但没有运气。有什么想法吗?

我正在使用tomcat 7.0.42和java 1.7.0_55以及CXF 3.0.1。 在java的rt.jar中,com.sun.xml.bind.marshaller.NamespacePrefixMapper不存在(这是异常的原因),但com.sun.xml.internal.bind.marshaller.NamespacePrefixMapper存在。为什么cxf没有采用这种实现方式?

由于

1 个答案:

答案 0 :(得分:4)

经过一天的搜索和绝望,在发布这个大问题之后,5分钟后我找到了解决方案。热闹!!!

我在我的pom中错过了这种依赖

<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-databinding-jaxb</artifactId>
    <version>3.0.1</version>
</dependency>

非常感谢