Java 使用ApacheCxf获取SOAP POST请求时出错,但curl可以正常工作
我有一个很奇怪的问题。我正在尝试通过HTTPS执行SOAP POST请求。当我从我的代码发送请求时,我得到了HTTP500错误。现在,从cxf日志中,如果我复制得到错误的相同SOAP消息(头部和主体),并使用一个简单的curl请求将其发布,那么工作正常。下面是我如何创建服务类和其他初始化Java 使用ApacheCxf获取SOAP POST请求时出错,但curl可以正常工作,java,apache,curl,https,cxf,Java,Apache,Curl,Https,Cxf,我有一个很奇怪的问题。我正在尝试通过HTTPS执行SOAP POST请求。当我从我的代码发送请求时,我得到了HTTP500错误。现在,从cxf日志中,如果我复制得到错误的相同SOAP消息(头部和主体),并使用一个简单的curl请求将其发布,那么工作正常。下面是我如何创建服务类和其他初始化 URL wsdlurl = SOAPWebServiceTransport.class.getClassLoader(). getResource("my.wsdl"); OnlinePort
URL wsdlurl = SOAPWebServiceTransport.class.getClassLoader().
getResource("my.wsdl");
OnlinePort service= new OnlinePortService(wsdlurl).getOnlinePortPort();
Client proxy = ClientProxy.getClient(service);
// Provides WS-Security
WSS4JOutInterceptor wss4jOut = new WSS4JOutInterceptor();
wss4jOut.setProperty("action", "UsernameToken");
wss4jOut.setProperty("user", userName);
wss4jOut.setProperty("passwordType", "PasswordText");
wss4jOut.setProperty("password", password);
wss4jOut.setProperty(WSHandlerConstants.ADD_UT_ELEMENTS,
WSConstants.NONCE_LN + " " + WSConstants.CREATED_LN);
wss4jOut.setProperty(WSHandlerConstants.PW_CALLBACK_CLASS, ServerPasswordCallback.class.getName());
proxy.getEndpoint().getOutInterceptors().add(wss4jOut);
setConduitProperties((HTTPConduit) proxy.getConduit(),url);
在setconductor方法中,我忽略了ssl检查(仅用于开发环境)并设置了一些头
TLSClientParameters tcp = new TLSClientParameters();
tcp.setDisableCNCheck(true);
// Creating Trust Manager
TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
} };
tcp.setTrustManagers(trustAllCerts);
conduit.setTlsClientParameters(tcp);
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setAllowChunking(false);
httpClientPolicy.setAccept("*/*");
httpClientPolicy.setContentType("text/xml;charset=UTF-8");
httpClientPolicy.setHost(url.split("/")[2]);
conduit.setClient(httpClientPolicy);
任何帮助都是值得赞赏的
Response-Code: 500
Encoding: ISO-8859-1
Content-Type: text/html;charset=ISO-8859-1
Headers: {connection=[close], content-type=[text/html;charset=ISO-8859-1],
Date=[Mon, 15 Jun 2015 06:42:09 GMT], Server=[Apache-Coyote/1.1],
Set-Cookie=[JSESSIONID=FF0E4F5DCA42F700FFAC46BBD039FC20; Path=/; Secure],
transfer-encoding=[chunked]}
Payload:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
> <html> <head> <meta http-equiv="Content-Type" content="text/html;
> charset=ISO-8859-1"/> <title>Error Page</title> </head> <body>Invalid
> Request </body> </html>
at org.apache.cxf.interceptor.StaxInInterceptor.handleMessage(StaxInInterceptor.java:79)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263)
at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:797)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1618)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1491)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1399)
at org.apache.cxf.io.CacheAndWriteOutputStream.postClose(CacheAndWriteOutputStream.java:47)
at org.apache.cxf.io.CachedOutputStream.close(CachedOutputStream.java:188)
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:646)
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:533)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:463)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:366)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:319)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:88)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:134)
Caused by: org.apache.cxf.interceptor.Fault: Response was of unexpected text/html ContentType. Incoming portion of HTML stream:
响应代码:500
编码:ISO-8859-1
内容类型:text/html;字符集=ISO-8859-1
标题:{connection=[close],content type=[text/html;charset=ISO-8859-1],
日期=[2015年6月15日星期一06:42:09 GMT],服务器=[Apache Coyote/1.1],
设置Cookie=[JSESSIONID=FF0E4F5DCA42F700FFAC46BBD039FC20;路径=/;安全],
传输编码=[chunked]}
有效载荷:
>错误页无效
>请求
位于org.apache.cxf.interceptor.staxinterceptor.handleMessage(staxinterceptor.java:79)
位于org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263)
位于org.apache.cxf.endpoint.clientmpl.onMessage(clientmpl.java:797)
http.httpconductor$WrappedOutputStream.handleResponseInternal(httpconductor.java:1618)
位于org.apache.cxf.transport.http.httpconductor$WrappedOutputStream.handleResponse(httpconductor.java:1491)
位于org.apache.cxf.transport.http.httpconductor$WrappedOutputStream.close(httpconductor.java:1399)
位于org.apache.cxf.io.CacheAndWriteOutputStream.postClose(CacheAndWriteOutputStream.java:47)
位于org.apache.cxf.io.CachedOutputStream.close(CachedOutputStream.java:188)
位于org.apache.cxf.transport.AbstractConductor.close(AbstractConductor.java:56)
位于org.apache.cxf.transport.http.httpconductor.close(httpconductor.java:646)
位于org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderdingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
位于org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263)
位于org.apache.cxf.endpoint.clientmpl.doInvoke(clientmpl.java:533)
位于org.apache.cxf.endpoint.clientmpl.invoke(clientmpl.java:463)
位于org.apache.cxf.endpoint.clientmpl.invoke(clientmpl.java:366)
位于org.apache.cxf.endpoint.clientmpl.invoke(clientmpl.java:319)
位于org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:88)
位于org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:134)
原因:org.apache.cxf.interceptor.Fault:响应为意外的text/html内容类型。HTML流的传入部分:
卷曲请求
curl-k--header“内容类型:text/xml;charset=UTF-8”--header“SOAPAction:”--data@soaprequest.xml
(当然,我们已经更改了一些url端口名称0
来自服务器的错误响应
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
<title>Error Page</title>
</head>
<body>Invalid Request
</body>
</html>
错误页
无效请求
如果无法访问服务器上的日志,可以尝试检查您的代码请求和curl请求是否不同
要做到这一点,您可以使用类似的嗅探器来嗅探http请求
Tcpmon作为客户端和服务器之间的代理运行。它拦截所有请求并打印每个请求和响应的详细信息。关键在于使用核心java HttpURLConnection来实现这一点 类似这样的方法有助于cause广告在没有任何框架的情况下发布Web服务调用:
public HttpURLConnection getHttpConn(String webservice_url) throws IOException {
URL endpoint = new URL(webservice_url);
URLConnection connection = endpoint.openConnection();
HttpURLConnection httpConn = (HttpURLConnection) connection;
byte[] encodedBytes = Base64.encodeBase64((getUsername()+":"+getPassword()).getBytes());
httpConn.setRequestMethod(getRequestMethod());
httpConn.setRequestProperty(HTTP_ACCEPT_ENCODING, getAccept_Encoding());
httpConn.setRequestProperty(HTTP_CONTENT_TYPE, getContentType());
httpConn.setRequestProperty(getContent_Length(), getContent_Length());
httpConn.setRequestProperty(HTTP_HOST, getHost());
httpConn.setRequestProperty(getConnection(), getConnection());
httpConn.setRequestProperty(HTTP_COOKIE2, getCookie2());
httpConn.setRequestProperty(HTTP_COOKIE, getCookie());
httpConn.setRequestProperty("Authorization", "Basic "+new String(encodedBytes));
httpConn.setDoOutput(true);
httpConn.setDoInput(true);
return httpConn;
}
确保在CXF配置文件(CXF.xml)中配置http客户端
如Apache CXF文档中所述:
1.添加http导管命名空间和xsd:
<beans ...
xmlns:http-conf="http://cxf.apache.org/transports/http/configuration
...
xsi:schemaLocation="...
http://cxf.apache.org/transports/http/configuration
http://cxf.apache.org/schemas/configuration/http-conf.xsd
...">
尝试使用作为代理并比较两个请求。头或请求正文中必须存在差异
Fiddler还能够解码TLS
祝大家好运。SOAP在xml上工作,我可以看到您有以下错误
原因:org.apache.cxf.interceptor.Fault:响应为意外的文本/html内容类型。html流的传入部分:
也就是说你的回复是HTML格式的,
响应代码:500
编码:ISO-8859-1
内容类型:text/html;chars
因此,您的Web服务可能有问题,请尝试使用SOAP UI
此外,这个链接将非常有助于讨论同样的问题。
检查WSDL URL
URL必须提供到?wsdl我最近遇到了类似于您的问题。我刚刚在依赖项中添加了两个工件:
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>${cxf.version}</version>
</dependency>
org.apache.cxf
cxf rt传输http
${cxf.version}
org.apache.cxf
cxf rt传输http jetty
${cxf.version}
这就是客户端堆栈跟踪。您能知道服务器端发生了什么吗?我的假设是,某些身份验证尝试出错,服务器发出了HTML响应。从CXF的角度来看,在curl
中:“响应是意外的文本/HTML”-表示服务器端出现问题。不,我们不可能看到服务器端发生了什么。是的,cxf失败,因为它接收到的是html响应,而不是基于soap的xml,但我想是因为服务器端出现了一些错误或验证异常。令人惊讶的是,具有几乎相同http头的相同soap请求正在工作我打赌你的内容类型头在请求发出之前被覆盖了,你能在从应用程序发送后检查请求头吗?@JacobMargason其发送的“内容类型”:“text/xml;charset=UTF-8”我检查了它你确定客户端使用的WSDL URL是正确的URL吗?Soap头和消息是e与我从cxf日志中复制并使用curl发送的消息完全相同。https可能存在一些问题,由于消息使用SSLAlready加密,因此难以跟踪,已尝试使用HttpURLConnec
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>${cxf.version}</version>
</dependency>