我正在尝试使用 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没有采用这种实现方式?
由于
答案 0 :(得分:4)
经过一天的搜索和绝望,在发布这个大问题之后,5分钟后我找到了解决方案。热闹!!!
我在我的pom中错过了这种依赖
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-databinding-jaxb</artifactId>
<version>3.0.1</version>
</dependency>
非常感谢