Sarfaraz Khan
Sarfaraz Khan

Reputation: 2186

Getting Error in SOAP POST request using Apache CXF but curl works

I'm having a very strange problem. I'm trying to do a SOAP POST request over HTTPS. When I'm sending the request from my code, I'm getting HTTP 500 error. Now from the cxf log if I copy the same SOAP message(header and body) that I got error for and post it using a simple curl request it's working fine. Below is how I'm creating service class and other initialization

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);

In the set conduit method I'm ignoring the ssl check (for development env only) and setting some header.

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);

Any help would be highly appreciable.

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: 

CURL Request

curl -k --header "Content-Type: text/xml;charset=UTF-8" --header "SOAPAction:" --data @soaprequest.xml https://url

Curl log in verbose (ofcourse have changed some url port names0

Error response from server

    <!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> 

Upvotes: 25

Views: 10659

Answers (6)

Nikolai  Shevchenko
Nikolai Shevchenko

Reputation: 7521

I've faced problem similar to yours recently. I've just added 2 artifacts into dependencies:

    <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>

Upvotes: 0

Vandanaa
Vandanaa

Reputation: 1

Check the WSDL URL.

URL has to be given till ?wsdl

Upvotes: 0

rohit thomas
rohit thomas

Reputation: 2322

SOAP works on xml and I can see the you have the following error

Caused by: org.apache.cxf.interceptor.Fault: Response was of unexpected text/html ContentType. Incoming portion of HTML stream:

Which is saying that your response is coming in HTML, Response-Code: 500 Encoding: ISO-8859-1 Content-Type: text/html;chars

So there might be a problem with your WebService try using SOAP UI

also this link will be quite helpful talks about the same issue. https://forums.mulesoft.com/questions/27468/web-service-consumer-response-was-of-unexpected-te.html

Upvotes: 2

Dan Filip
Dan Filip

Reputation: 26

try using Fiddler as a proxy and compare both requests. there must be a difference either in the headers or in the request body.

Fiddler is also capable of decoding TLS.

good luck to anyone..

Upvotes: 0

Abdel
Abdel

Reputation: 580

The turnaround was to use core java HttpURLConnection to achieve this.

A method something like this helped the cause ad post a webservice call without any framework.:

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;
}

Ensure to configure the http client in the CXF config file (cxf.xml).

As documented in Apache CXF document:

1.Add the http-conduit namespace and 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
       ...">

2.Add the http-conduit tag/element and set the RecieveTimeout/ConnectionTimeout to 180000ms:

<http-conf:conduit name="*.http-conduit">
      <http-conf:client 
                      ConnectionTimeout="300000"
                      ReceiveTimeout="300000"/>       
</http-conf:conduit>

Upvotes: 0

Davide Lorenzo MARINO
Davide Lorenzo MARINO

Reputation: 26946

If you can't access the log on the server you can try to check if your code request and the curl request are different.

To do that you can sniff the http request with a sniffer like tcpmon.

Tcpmon operates as a proxy between your client and the server. It intercepts all requests and print the details of each request and response.

Upvotes: 0

Related Questions