使用 Apache CXF 调用 SOAP API 时发生 ClassCastException

Posted

技术标签:

【中文标题】使用 Apache CXF 调用 SOAP API 时发生 ClassCastException【英文标题】:ClassCastException while calling SOAP API using Apache CXF 【发布时间】:2014-02-19 14:53:56 【问题描述】:

我正在使用 Maven、Java 1.6、Apache CXF。在某些类 Apache CXF 中调用 Soap API 时,我遇到了一些 Class Cast 异常。这是堆栈跟踪。

javax.xml.ws.soap.SOAPFaultException:java.net.URL 无法转换为 java.lang.String 在 org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:157) 在 com.sun.proxy.$Proxy83.importCapturedData(未知来源) 在 com.flipkart.dynamics.api.DynamicsClientService.handleDataLoadRequest(DynamicsClientService.java:109) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 在 java.lang.reflect.Method.invoke(Method.java:597) 在 com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60) 在 com.sun.jersey.server.impl.model.method.dispatch.Abs​​tractResourceMethodDispatchProvider$ResponseOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:205) 在 com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75) 在 com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:302) 在 com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147) 在 com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108) 在 com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147) 在 com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84) 在 com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1480) 在 com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1411) 在 com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1360) 在 com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1350) 在 com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416) 在 com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:538) 在 com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:716) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:728) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 在 com.flipkart.recon.api.filter.ContentTypeFilter.doFilter(ContentTypeFilter.java:73) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 在 org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) 在 org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) 在 org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) 在 org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171) 在 org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100) 在 org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953) 在 org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) 在 org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408) 在 org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041) 在 org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603) 在 org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310) 在 java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918) 在 java.lang.Thread.run(Thread.java:695) 原因:java.lang.ClassCastException:java.net.URL 无法转换为 java.lang.String 在 org.apache.cxf.endpoint.AbstractConduitSelector.getSelectedConduit(AbstractConduitSelector.java:99) 在 org.apache.cxf.endpoint.UpfrontConduitSelector.prepare(UpfrontConduitSelector.java:63) 在 org.apache.cxf.endpoint.ClientImpl.prepareConduitSelector(ClientImpl.java:886) 在 org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:560) 在 org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:474) 在 org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:377) 在 org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:330) 在 org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96) 在 org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:135) ... 41 更多 [2014-01-28 16:07:44.572] 错误 [http-bio-8082-exec-2][ContentTypeFilter][ContentTypeFilter.java:93] 未处理的异常。 javax.xml.ws.soap.SOAPFaultException:java.net.URL 无法转换为 java.lang.String 在 org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:157) ~[cxf-2.7.8.jar:2.7.8] 在 com.sun.proxy.$Proxy83.importCapturedData(Unknown Source) ~[na:na] 在 com.flipkart.dynamics.api.DynamicsClientService.handleDataLoadRequest(DynamicsClientService.java:109) ~[DynamicsClientService.class:na] 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.6.0_65] 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) ~[na:1.6.0_65] 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) ~[na:1.6.0_65] 在 java.lang.reflect.Method.invoke(Method.java:597) ~[na:1.6.0_65] 在 com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60) ~[jersey-server-1.14.jar:1.14] 在 com.sun.jersey.server.impl.model.method.dispatch.Abs​​tractResourceMethodDispatchProvider$ResponseOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:205) ~[jersey-server-1.14.jar:1.14] 在 com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75) ~[jersey-server-1.14.jar:1.14] 在 com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:302) ~[jersey-server-1.14.jar:1.14] 在 com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147) ~[jersey-server-1.14.jar:1.14] 在 com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108) ~[jersey-server-1.14.jar:1.14] 在 com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147) ~[jersey-server-1.14.jar:1.14] 在 com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84) ~[jersey-server-1.14.jar:1.14] 在 com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1480) ~[jersey-server-1.14.jar:1.14] 在 com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1411) ~[jersey-server-1.14.jar:1.14] 在 com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1360) ~[jersey-server-1.14.jar:1.14] 在 com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1350) ~[jersey-server-1.14.jar:1.14] 在 com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416) ~[jersey-servlet-1.14.jar:1.14] 在 com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:538) ~[jersey-servlet-1.14.jar:1.14] 在 com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:716) ~[jersey-servlet-1.14.jar:1.14] 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:728) ~[servlet-api.jar:na] 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) [catalina.jar:7.0.47] 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) [catalina.jar:7.0.47] 在 com.flipkart.recon.api.filter.ContentTypeFilter.doFilter(ContentTypeFilter.java:73) ~[ContentTypeFilter.class:na] 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) [catalina.jar:7.0.47] 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) [catalina.jar:7.0.47] 在 org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) [catalina.jar:7.0.47] 在 org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) [catalina.jar:7.0.47] 在 org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) [catalina.jar:7.0.47] 在 org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171) [catalina.jar:7.0.47] 在 org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100) [catalina.jar:7.0.47] 在 org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953) [catalina.jar:7.0.47] 在 org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) [catalina.jar:7.0.47] 在 org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408) [catalina.jar:7.0.47] 在 org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041) [tomcat-coyote.jar:7.0.47] 在 org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603) [tomcat-coyote.jar:7.0.47] 在 org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310) [tomcat-coyote.jar:7.0.47] 在 java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895) [na:1.6.0_65] 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918) [na:1.6.0_65] 在 java.lang.Thread.run(Thread.java:695) [na:1.6.0_65] 原因:java.lang.ClassCastException:java.net.URL 无法转换为 java.lang.String 在 org.apache.cxf.endpoint.AbstractConduitSelector.getSelectedConduit(AbstractConduitSelector.java:99) ~[cxf-2.7.8.jar:2.7.8] 在 org.apache.cxf.endpoint.UpfrontConduitSelector.prepare(UpfrontConduitSelector.java:63) ~[cxf-2.7.8.jar:2.7.8] 在 org.apache.cxf.endpoint.ClientImpl.prepareConduitSelector(ClientImpl.java:886) ~[cxf-2.7.8.jar:2.7.8] 在 org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:560) ~[cxf-2.7.8.jar:2.7.8] 在 org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:474) ~[cxf-2.7.8.jar:2.7.8] 在 org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:377) ~[cxf-2.7.8.jar:2.7.8] 在 org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:330) ~[cxf-2.7.8.jar:2.7.8] 在 org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96) ~[cxf-2.7.8.jar:2.7.8] 在 org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:135) ~[cxf-2.7.8.jar:2.7.8] ...省略了41个常用框架

这是我正在使用的代码:

try
    
        wsdlURL =
                new URL("some http url with requiring basic authentication");
    
    catch (MalformedURLException e)
    
        // TODO Auto-generated catch block
        e.printStackTrace();
    

    System.out.println(wsdlURL);

    OPSRequestManagement opsRequestManagement = new OPSRequestManagement(wsdlURL, SERVICE_NAME);
    OPSRequestManagementPort opsRequestManagementPort = opsRequestManagement.getOPSRequestManagementPort();

    Map<String, Object> req_ctx = ((BindingProvider) opsRequestManagementPort).getRequestContext();
    req_ctx.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, wsdlURL);

    Map<String, List<String>> headers = new HashMap<String, List<String>>();
    headers.put("Username", Collections.singletonList("domain\\username"));
    headers.put("Password", Collections.singletonList("password"));
    req_ctx.put(MessageContext.HTTP_REQUEST_HEADERS, headers);

    boolean resp;

    List<CapturedData> capturedDataList = dynamicsDao.getCapturedData(startDate.getTime(), endDate.getTime());
    FKPG fkpg = new FKPG();
    fkpg.getContent().addAll(capturedDataList);
    resp = opsRequestManagementPort.importCapturedData(fkpg);

【问题讨论】:

拜托,您能指出引发异常的行号吗? 【参考方案1】:

@sadhu 的回答为我自己的问题指明了正确的方向,但这对我来说太神秘了。

拿着这个sn-p:

wsdlURL = new URL("some http url with requiring basic authentication");

这告诉我们 wsdlURL 的类型是 java.net.URL。接下来我们发现:

Map<String, Object> req_ctx = ((BindingProvider) opsRequestManagementPort).getRequestContext();
req_ctx.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, wsdlURL);

要解决此问题,请将最后一行更改为:

req_ctx.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, wsdlURL.toExternalForm());

关键是您应该在地图中放置一个String 对象,而不是URL 实例。


为防止将来发生这种情况,请始终检查 Javadoc。这就是ENDPOINT_ADDRESS_PROPERTY 所说的:(强调我的)

标准属性:目标服务端点地址。端点地址规范的 URI 方案必须与正在使用的绑定的协议/传输绑定相对应。

类型:java.lang.String

【讨论】:

【参考方案2】:

我很确定,wsdlURL 的类型是 String,它不应该是。而是

URL wsdlURL

【讨论】:

以上是关于使用 Apache CXF 调用 SOAP API 时发生 ClassCastException的主要内容,如果未能解决你的问题,请参考以下文章

apache CXF wsdl2java工具的使用

cxf的soap风格+spirng4+maven 客户端

Apache CXF 中基于 WebSocket 的 SOAP?

使用 Apache CXF 在 SOAP POST 请求中出错,但 curl 有效

Apache CXF 入门详解

CXF方式搭建本地webservice服务和soap方式调用踩坑