I have a strange situation going on while implementing Web service client.
Request fired from SOAP UI is success and the HTTP request is as below:
POST http://xxxxxxxxxx/xx/xx/xxxxx/xxxxx HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: text/xml;charset=UTF-8
SOAPAction: "CreateUserSoap"
Content-Length: 1490
Host: xxxxxxxxxxxxxxxxxxx.net
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
Cookie: SMCHALLENGE=YES
Cookie2: $Version=1
Authorization: Basic ZHFhbgfdd6RFFQcdfgdm9vccQ=
<soap........./>
However when i fire the web service request from the application, for which i use apace cxf following HHTP Request is generated and i get a 403:Forbidden Error
ID: 1
Address: http://xxxxxxxxxx/xx/xx/xxxxx/xxxxx
Encoding: UTF-8
Http-Method: POST
Content-Type: text/xml
Headers: {Accept=[*/*], Authorization=[Basic ZHFhbgfdd6RFFQcdfgdm9vccQ=], SOAPAction= ["CreateUserSoap"]}
Payload: <soap....... />
I am not sure if the apache - cxf is generating the right http header as expected by the server. the soap envelope is same in both cases.
Below is the implementing java client code:
ClientWs clientWS= new ClientWs ();
ClientWSPortType portType = clientWS.getClientWSPort();
BindingProvider provider = (BindingProvider) portType;
Header dummyHeader = new Header(new QName("http://clientWS/wsdl", "ClientWS"), documentBuilder.parse(new ByteArrayInputStream(xmlString2.getBytes("UTF-8"))).getDocumentElement() ); --parsing the soap mesage
headers.add(dummyHeader);
provider.getRequestContext().put(Header.HEADER_LIST, headers);
provider.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, user_name);
provider.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, pass_word);
Well, no one ansered neither was i able to do this with Apache CXF.
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;
}
Related
I am sending a simple POST request with the built-in HttpURLConnection class, but I want to change the way Java separates the headers from the body (look at the outputs of tcpflow -a port 80 below). Here is the code:
// Create HttpURLConnection object
URL url = new URL("http://httpbin.org/post");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// Set request method
connection.setRequestMethod("POST");
// Write body and "Content-Length" header
String body = "This+is+the+body+of+the+post+request.";
connection.setRequestProperty("Content-Length",
String.valueOf(body.length()));
connection.setDoOutput(true);
connection.getOutputStream().write(body.getBytes("US-ASCII"));
// Send request
int responseCode = connection.getResponseCode();
When I execute that code and look at what Java actually sends using tcpflow -a port 80 (prints all requests/responses on port 80), I see the following (I cut away the response):
192.168.178.113.54654-054.225.177.165.00080: POST /post HTTP/1.1
User-Agent: Java/9
Host: httpbin.org
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
Content-type: application/x-www-form-urlencoded
Content-Length: 37
192.168.178.113.54654-054.225.177.165.00080: This is the body of the post request.
The headers are correct, the body is correct. But I can see that the body is transferred in a separate connection. I know that this is a problem with java.net.HttpURLConnection because when I try the same with Apache's HttpClient, tcpflow -a port 80 gives me:
192.168.178.113.39708-054.243.202.193.00080: POST /post HTTP/1.1
Content-Length: 37
Host: httpbin.org
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.5.3 (Java/9)
Accept-Encoding: gzip,deflate
This+is+the+body+of+the+post+request.
Here the body is sent with the headers, separated with just /r/n/r/n. I would like the Java library (java.net.HttpURLConnection) to do the same. Is that possible?
EDIT: I found out that the reason the server rejected my requests was not that the body was in a different packet (packet, not connection, as Julian Reschke pointed out) than the headers but just that I sent the wrong data facepalm.
I am able to set content type using cxf library but I don't know how to set Authorization header. Whenever I set user name and password then it set Authorization header and encode whole value and add Basic. I don't want to do this. I want to add Authorization header with plain string which ever I provide. Please help me to solve out this problem.
AMPServices services = new AMPServices();
CoreXmlPort coreXmlPort = services.getAMPSoapService();
Client client = ClientProxy.getClient(coreXmlPort);
HTTPConduit httpConduit = (HTTPConduit) client.getConduit();
HTTPClientPolicy httpClientPolicy=httpConduit.getClient();
String contentType=httpClientPolicy.getContentType();
contentType="application/soap+xml; type=vnd.iShip.AMP.SOAP; charset=UTF-8";
httpClientPolicy.setContentType(contentType);
AuthorizationPolicy authorizationPolicy = new AuthorizationPolicy();
authorizationPolicy.setUserName("username");
authorizationPolicy.setPassword("password");
httpConduit.setAuthorization(authorizationPolicy);
It generates following request xml.
POST https://api.iship.com/Root/Enterprises/Pitney%20Bowes/Progistics; HTTP/1.1
Content-Type: application/soap+xml; type=vnd.iShip.AMP.SOAP; charset=UTF-8
Accept: */*
Authorization: Basic aXNoaXAgcGIvd3NkZXZlbDowNzZhNjFjYTM5MDcxODAxODVjNWRkMjM2YTdkMzZhNGQ1ODg5OWFj
User-Agent: Apache CXF 3.1.0
Cache-Control: no-cache
Pragma: no-cache
Host: api.iship.com
Connection: keep-alive
Content-Length: 246
But I want this type of request
POST https://api.iship.com/Root/Enterprises/Pitney%20Bowes/Progistics; HTTP/1.1
Content-Type: application/soap+xml; type=vnd.iShip.AMP.SOAP; charset=UTF-8
Accept: */*
Authorization: username;password
User-Agent: Apache CXF 3.1.0
Cache-Control: no-cache
Pragma: no-cache
Host: api.iship.com
Connection: keep-alive
Content-Length: 246
But I was not able to do it. Please help me to solve out this problem.
Thanks,
Awadhendra
I think you are trying to call is a RestFul Service, so that's why the server side always response with a different content type than you expected (json instead of soap/xml). Is your url endpoint based on http protocol? If yes, do you need send additional parameters to this url?
The issue here is that the client you are using to interact with Webservice expecting XML based Soap Messages , while the service is serving JSON as a return media.
Either convert your client to use the JSON format and communicate using that, or alternatively use the XML based endpoint , consult with webservice provider for that.
im using a generated axis client to consume a service that requires headers
when using SOAPUI, i add the headers and the request looks like this
POST https://fttoo/service/v3.2/SOAP HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: text/xml;charset=UTF-8
SOAPAction: ""
Authorization: Bearer 123
Content-Length: 270
Host: my host
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
when trying to set the headers with code i'm doing the following
proxy = (SessionServiceImplServiceSoapBindingStub)locator.getSessionService();
proxy._setProperty("Authorization", "Bearer 123");
this is not working well and i get Error 401, when inspecting the proxy object i see that a property called cachedProperties has the value of {Authorization=Bearer 123}
I've also tried proxy._setProperty(HTTPConstants.HEADER_AUTHORIZATION, "Bearer 123");
and also inside the stub, in the _call object....
given the fact that axis 1 is very old i generated a new web client using CXF instead of Axis, this way i was able to use cxf api to place the headers
nni have a problem calling a web service using jersey client.
I tried successfully as a test with : "http://query.yahooapis.com/v1/public/yql?q=select%20item%20from%20weather.forecast%20where%20location%3D%2248907%22&format=json"
using this code :
Client client = Client.create();
WebResource webResource = client.resource("http://query.yahooapis.com/v1/public/yql?q=select%20item%20from%20weather.forecast%20where%20location%3D%2248907%22&format=json");
ClientResponse response = webResource.accept("application/json").get(ClientResponse.class);
if (response.getStatus() != 200) {
throw new RuntimeException("Failed : HTTP error code : " + response.getStatus());
}
String json = response.getEntity(String.class);
System.out.println(json);
but i can't do it when i call amazon webservice : http://ws.amazon.com/widgets/q?Operation=GetResults&Keywords=cool&SearchIndex=All&multipageStart=0&InstanceId=0&multipageCount=10&TemplateId=8002&ServiceVersion=20070822&MarketPlace=US
Is it because, I get a json file as response ?
Any help please ?
After experimenting with the Amazon web service with various form HTTP requests. I finally figured out that the problem is because of the User-Agent value sent in the HTTP Header.
For some reason, Amazon Rest Service is not able to handle the presence of period character . in the HTTP Header under User-Agent.
When sending a HTTP request with . as below
GET http://ws.amazon.com/widgets/q?Operation=GetResults&Keywords=cool&SearchIndex=All&multipageStart=0&InstanceId=0&multipageCount=10&TemplateId=8002&ServiceVersion=20070822&MarketPlace=US HTTP/1.1
User-Agent: Java.
Host: ws.amazon.com
Connection: keep-alive
Amazon WS sends a HTTP response without Body content
HTTP/1.1 200 OK
Date: Fri, 27 Sep 2013 19:29:54 GMT
Server: Server
Content-Length: 0
Vary: Accept-Encoding,User-Agent
Cneonction: close
Content-Type: text/plain
If the . is removed from the Content-Type, the response body does contain the detailed Json Content. This most likely looks like an issue on Amazon Rest Service implementation.
You can change the code as follows to see the Json content and get away with the problem
ClientResponse response = webResource.header("User-Agent", "SomeAgentNameWithoutPeriodChar").get(ClientResponse.class);
I'm trying to use the Apache HttpClient 4.1.1 library (http://hc.apache.org/httpcomponents-client-ga/tutorial/html/authentication.html) to access sites from behind my company's proxy that uses the ISA Server with NTLM authentication but I keep getting an HTTP 407 Proxy Authentication Required error:
Code Snippet
HttpHost proxy = new HttpHost("myProxyHost", 80, "http");
DefaultHttpClient httpClient = new DefaultHttpClient();
httpClient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
NTCredentials creds = new NTCredentials("myWindowsUserName", "myWindowsPwd", "localhost", "myCompanyDomain");
AuthScope authScope = new AuthScope("myProxyHost", 80, "", "NTLM");
httpClient.getCredentialsProvider().setCredentials(authScope, creds);
HttpHost target = new HttpHost("www.google.com", 80, "http");
HttpGet get = new HttpGet("/");
System.out.println("executing request to " + target + " via " + proxy);
HttpResponse rsp = httpClient.execute(target, get);
System.out.println("----------------------------------------");
System.out.println(rsp.getStatusLine());
Header[] headers = rsp.getAllHeaders();
for (int i = 0; i<headers.length; i++) {
System.out.println(headers[i]);
}
System.out.println("----------------------------------------");
O/P
executing request to http://www.google.com:80 via http://myProxyHost:80
----------------------------------------
HTTP/1.1 407 Proxy Authentication Required ( The ISA Server requires authorization to fulfill the request. Access to the Web Proxy filter is denied. )
Via: 1.1 myCompanyServer
Proxy-Authenticate: Negotiate
Proxy-Authenticate: Kerberos
Proxy-Authenticate: NTLM
Connection: Keep-Alive
Proxy-Connection: Keep-Alive
Pragma: no-cache
Cache-Control: no-cache
Content-Type: text/html
Content-Length: 4120
----------------------------------------
What am I missing here?
Update:
In the same environment, code using the JDK URL and URLConnection classes works!
Working Code Snippet
System.setProperty("http.proxyHost", "myProxyHost");
System.setProperty("http.proxyPort", "80");
URL url = new URL("http://www.google.com");
URLConnection con = url.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
O/P
Google window.google={kEI:"_N3cTaLFMY6cvgOH9MypDw",...
I had a similar problem with HttpClient 4.1.2. For me, it was resolved by reverting to HttpClient 4.0.3. I could never get NTLM working with 4.1.2 using either the built-in implementation or using JCIFS.
If you have no issues with LGPL licensed software you can try using NTLM engine developed by the Samba JCIFS project instead of the internal one used by Apache HttpClient per default.
See this document for detailed instructions:
http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/src/site/apt/ntlm.apt
PS: JDK URL and URLConnection classes work because they make use of platform specific calls when running on Microsoft Windows