JBOSS 上的 apache cxf 客户端的 Web 服务请求 (>8KB) 失败 - HTTP 响应“411:需要长度”
Web service request (>8KB) failed with apache cxf client on JBOSS - HTTP response '411: Length Required'
Web 应用程序正在使用 apache cxf 客户端向远程 Web 服务发送请求。
当此 Web 应用程序部署在 Tomcat 上时一切正常。
当此 Web 应用程序部署在 JBOSS 并且正文(信封)的大小大于 8 KB 时,请求发送失败;生成了以下错误:
17:57:15,387 WARNING [org.apache.cxf.phase.PhaseInterceptorChain (ConnectorExecutor-21) Interceptor for xxx#{http://cxf.apache.org/jaxws/dispatch}Invoke has thrown exception, unwinding now: org.apache.cxf.interceptor.Fault: Could not send Message.
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:64)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:531)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:461)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:364)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:317)
at org.apache.cxf.endpoint.ClientImpl.invokeWrapped(ClientImpl.java:352)
at org.apache.cxf.jaxws.DispatchImpl.invoke(DispatchImpl.java:381)
at org.apache.cxf.jaxws.DispatchImpl.invoke(DispatchImpl.java:241)
...
at java.util.concurrent.FutureTask.run(Unknown Source) [rt.jar:1.7.0_45]
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [rt.jar:1.7.0_45]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [rt.jar:1.7.0_45]
at java.lang.Thread.run(Unknown Source) [rt.jar:1.7.0_45]
Caused by: org.apache.cxf.transport.http.HTTPException: HTTP response '411: Length Required' when communicating with ...
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1554)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1493)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1401)
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:648)
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
... 17 more
HTTP 流模式似乎已切换到 chunked。
What do you think of this first assumption?
在官方的 apache cxf 文档中可以找到,可以提供 spring 配置文件以更改 cxf 客户端行为。
What is the configuration file content?
I answer to my own question, because after additional tests, the configuration described below worked for me.
首先,错误的产生可能是cxf客户端自动切换到chunked传输模式;实际上,此答案中描述的配置更改会强制 cxf 客户端 不使用 分块,然后成功发送信封大小大于 8 KB 的请求。
根据 cxf apache 官方文档,可以使用 Spring 配置文件更改 cxf 客户端行为:
- https://cxf.apache.org/docs/client-http-transport-including-ssl-support.html
- https://cxf.apache.org/docs/configuration.html
不需要更改java客户端的代码行。
- 1- cxf 配置文件
创建cxf.xmlspring配置文件:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:http-conf="http://cxf.apache.org/transports/http/configuration"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<http-conf:conduit name="*.http-conduit">
<http-conf:client AllowChunking="false"/>
</http-conf:conduit>
</beans>
- 2- cxf.config.file.url java 系统 属性
编辑 JBOSS 批处理或脚本文件,以便将此系统 属性 添加到 java 命令。
值为URL指向cxf.xml文件,windows示例如下:
-Dcxf.config.file.url=file:/C:/JBoss-7.1.1.Final/standalone/configuration/cxf.xml
There is below an example for Linux/UNIX:
-Dcxf.config.file.url=file:///home/jay/as/JBoss-7.1.1.Final/standalone/configuration/cxf.xml
- 3- 重启 JBOSS
- 4- 测试
- 5- 忽略发送请求时产生的WARNING信息
16:23:03,388 INFO [org.apache.cxf.bus.spring.ControlledValidationXmlBeanDefinitionReader] (ConnectorExecutor-1) Loading XML bean definitions from URL [file:/C:/JBoss-7.1.1.Final/standalone/configuration/cxf.xml]
16:23:06,535 WARNING [org.jboss.wsf.stack.cxf.client.configuration.JBossWSSpringBusFactory] (ConnectorExecutor-1) INITIAL_APP_CONTEXT_CREATION_FAILED_MSG: org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://cxf.apache.org/transports/http/configuration]
Offending resource: URL [file:/C:/JBoss-7.1.1.Final/standalone/configuration/cxf.xml]
at org.springframework.beans.factory.parsing.FailFastProblemReporter.error(FailFastProblemReporter.java:68) [spring-beans-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:85) [spring-beans-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:80) [spring-beans-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.error(BeanDefinitionParserDelegate.java:316) [spring-beans-3.1.2.RELEASE.jar:3.1.2.RELEASE]
我认为应该找到 http://cxf.apache.org/transports/http/configuration XML 模式命名空间的 NamespaceHandler 因为下面有这个 jar:
C:/JBoss-7.1.1.Final/modules/org/apache/cxf/main/cxf-rt-transports-http-2.4.6.jar
Anyway, the webservice request is successfuly sent !!
Web 应用程序正在使用 apache cxf 客户端向远程 Web 服务发送请求。
当此 Web 应用程序部署在 Tomcat 上时一切正常。
当此 Web 应用程序部署在 JBOSS 并且正文(信封)的大小大于 8 KB 时,请求发送失败;生成了以下错误:
17:57:15,387 WARNING [org.apache.cxf.phase.PhaseInterceptorChain (ConnectorExecutor-21) Interceptor for xxx#{http://cxf.apache.org/jaxws/dispatch}Invoke has thrown exception, unwinding now: org.apache.cxf.interceptor.Fault: Could not send Message.
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:64)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:531)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:461)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:364)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:317)
at org.apache.cxf.endpoint.ClientImpl.invokeWrapped(ClientImpl.java:352)
at org.apache.cxf.jaxws.DispatchImpl.invoke(DispatchImpl.java:381)
at org.apache.cxf.jaxws.DispatchImpl.invoke(DispatchImpl.java:241)
...
at java.util.concurrent.FutureTask.run(Unknown Source) [rt.jar:1.7.0_45]
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [rt.jar:1.7.0_45]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [rt.jar:1.7.0_45]
at java.lang.Thread.run(Unknown Source) [rt.jar:1.7.0_45]
Caused by: org.apache.cxf.transport.http.HTTPException: HTTP response '411: Length Required' when communicating with ...
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1554)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1493)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1401)
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:648)
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
... 17 more
HTTP 流模式似乎已切换到 chunked。
What do you think of this first assumption?
在官方的 apache cxf 文档中可以找到,可以提供 spring 配置文件以更改 cxf 客户端行为。
What is the configuration file content?
I answer to my own question, because after additional tests, the configuration described below worked for me.
首先,错误的产生可能是cxf客户端自动切换到chunked传输模式;实际上,此答案中描述的配置更改会强制 cxf 客户端 不使用 分块,然后成功发送信封大小大于 8 KB 的请求。
根据 cxf apache 官方文档,可以使用 Spring 配置文件更改 cxf 客户端行为:
- https://cxf.apache.org/docs/client-http-transport-including-ssl-support.html
- https://cxf.apache.org/docs/configuration.html
不需要更改java客户端的代码行。
- 1- cxf 配置文件
创建cxf.xmlspring配置文件:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:http-conf="http://cxf.apache.org/transports/http/configuration"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<http-conf:conduit name="*.http-conduit">
<http-conf:client AllowChunking="false"/>
</http-conf:conduit>
</beans>
- 2- cxf.config.file.url java 系统 属性
编辑 JBOSS 批处理或脚本文件,以便将此系统 属性 添加到 java 命令。
值为URL指向cxf.xml文件,windows示例如下:
-Dcxf.config.file.url=file:/C:/JBoss-7.1.1.Final/standalone/configuration/cxf.xml
There is below an example for Linux/UNIX:
-Dcxf.config.file.url=file:///home/jay/as/JBoss-7.1.1.Final/standalone/configuration/cxf.xml
- 3- 重启 JBOSS
- 4- 测试
- 5- 忽略发送请求时产生的WARNING信息
16:23:03,388 INFO [org.apache.cxf.bus.spring.ControlledValidationXmlBeanDefinitionReader] (ConnectorExecutor-1) Loading XML bean definitions from URL [file:/C:/JBoss-7.1.1.Final/standalone/configuration/cxf.xml]
16:23:06,535 WARNING [org.jboss.wsf.stack.cxf.client.configuration.JBossWSSpringBusFactory] (ConnectorExecutor-1) INITIAL_APP_CONTEXT_CREATION_FAILED_MSG: org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://cxf.apache.org/transports/http/configuration]
Offending resource: URL [file:/C:/JBoss-7.1.1.Final/standalone/configuration/cxf.xml]
at org.springframework.beans.factory.parsing.FailFastProblemReporter.error(FailFastProblemReporter.java:68) [spring-beans-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:85) [spring-beans-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:80) [spring-beans-3.1.2.RELEASE.jar:3.1.2.RELEASE]
at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.error(BeanDefinitionParserDelegate.java:316) [spring-beans-3.1.2.RELEASE.jar:3.1.2.RELEASE]
我认为应该找到 http://cxf.apache.org/transports/http/configuration XML 模式命名空间的 NamespaceHandler 因为下面有这个 jar:
C:/JBoss-7.1.1.Final/modules/org/apache/cxf/main/cxf-rt-transports-http-2.4.6.jar
Anyway, the webservice request is successfuly sent !!