How to use Apache HttpClient while the underlying connection is stateful? - java

I have googled a lot about how to use HttpClient with multithreading.
Most of them suggest using the ThreadSafeClientConnManager.
But my application has to login some host(a login form page) so that HttpClient obtains a underlying stateful connection.
Can ThreadSafeClientConnManager hold the login state if multithreading?

Read the following sections from this page: HttpClient Tutorial about Cookies and state management
3.8. HTTP state management and execution context
3.9. Per user / thread state management
and this maybe that code you want:
HttpClient httpclient = new DefaultHttpClient();
// Create a local instance of cookie store
CookieStore cookieStore = new BasicCookieStore();
// Create local HTTP context
HttpContext localContext = new BasicHttpContext();
// Bind custom cookie store to the local context
localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
HttpGet httpget = new HttpGet("http://www.google.com/");
// Pass local context as a parameter
HttpResponse response = httpclient.execute(httpget, localContext);

Yes, HttpClient will maintain state (E.g. session cookies) with thread safe connection manager.
If you face any issues with login, try switching to "Browser compatibility" cookie policy.
client.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);

Related

httpClient can not handle ipv6 cookies

I use httpClient 4.5 with java. I want to send http GET/POST with "CloseableHttpClient" class.
BasicCookieStore cookieStore = new BasicCookieStore();
CloseableHttpClient httpClient = HttpClients.custom()
.setSSLSocketFactory(sslSF).setDefaultCookieStore(cookieStore)
.build();
//.......
//.......
HttpGet httpGet = new HttpGet(protocol+"://"+ip+"/");
CloseableHttpResponse response1 = httpClient.execute(httpGet);
Actually it works with ipv4. But when it comes to ipv6, it apears can not keep the session ID alive.
I have printed out the session ID to check.
In ipv4 the session ID could be sent out correctly as following.
Cookie: SID=mdplxtedrjokwhxj
However the same code can not work with ipv6, are there difference between ipv4 and ipv6?
Or is this a current limitation in httpClient 4.5?

How to pass jessionid in cookies using httpclient in java

I get the jsessionid value from the server and try to pass the value in the cookie to avoid creation of multiple sessions for each request that is made
I use the below code to set the cookie value and add it to the context but it always gives me a 401 Authentication error no matter whatever additional parameters I add to the cookie
HttpClientContext localContext = HttpClientContext.create();
BasicCookieStore cookieStore = new BasicCookieStore();
BasicClientCookie cookie = new BasicClientCookie("JSESSIONID", sessionID);
cookie.setDomain("www.example.com");
cookie.setPath("/");
cookie.setVersion(0);
cookie.setAttribute("JSESSIONID", sessionID);
cookieStore.addCookie(cookie);
localContext.setAttribute(HttpClientContext.COOKIE_STORE, cookieStore);
localContext.setCookieStore(cookieStore);
response = httpClient.execute(get,localContext);
Also the httpclient that I am using is the CloseableHttpClient
Please suggest any other workarounds or correct me if I do something wrong in the above code
Thanks in advance

setting Cookie: JSESSIONID on client request manually

im making a swing application which will sign in to a server; were im using HttpURLConnection to submit my request and get my response.
problem is when the httpRequest gets to the server the "Cookie: JSESSIONID" header is there, session id is there; but the request.getSession(false) will always return null.
here is the code which i use to set the header on the client:
connection.setRequestProperty("Cookie: JSESSIONID", client.getSessionId());
any help would be apprectiated
HttpPost httppost = new HttpPost(postData);
CookieStore cookieStore = new BasicCookieStore();
BasicClientCookie cookie = new BasicClientCookie("JSESSIONID", getSessionId());
//cookie.setDomain("your domain");
cookie.setPath("/");
cookieStore.addCookie(cookie);
client.setCookieStore(cookieStore);
response = client.execute(httppost);
See also this Java: How to make a HTTP browsing session and this Apache HttpClient 4.0.3 - how do I set cookie with sessionID for POST request

apache commons httpclient 4.23 form login problems different session cookies used in different requests

I have a protected resource which requires me to login. Im using the commons client with the following code block.
HttpClient httpClient = new HttpClient();
httpClient.getParams().setParameter("http.protocol.cookie-policy", CookiePolicy.BROWSER_COMPATIBILITY);
httpClient.getParams().setParameter("http.protocol.single-cookie-header", Boolean.TRUE);
PostMethod postMethod = new PostMethod("/admin/adminlogon.do");
postMethod.setRequestEntity(new StringRequestEntity("action=logon&adminUser=admin&adminPassword=password",
"application/x-www-form-urlencoded",
"UTF-8"));
postMethod.addParameter("action","logon");
postMethod.addParameter("adminUser","admin");
postMethod.addParameter("adminPassword","password");
httpClient.executeMethod(postMethod);
String response2 = postMethod.getResponseBodyAsString();
Above is where I basically login. This works fine im getting a nice little JSESSIONID cookie back.
GetMethod get = new GetMethod("/admin/api.do?action=getSomeJson");
httpClient.executeMethod(get);
When I check the logic on the sever the for the 2nd request I notice that we are using a different JSESSIONID. Therefore the get seems to fail to log in. I was under the impression the httpClient managed the cookies and sent the same cookie back. When I log into my app normally through the UI I see the same cookie in each request just not in the this test code.
String s = get.getResponseBodyAsString();
get.releaseConnection();
Do I need to do something with the httpClient to ensure it uses the same cookies from the first post request when it does its get request??
Thanks in advance.
Your assumption regarding HTTP client cookie behavior is correct.
In your case your not use the same httpClient instance. To fix it you need to allocate the httpClient only once (in PostConstructor):
httpClient = new DefaultHttpClient(); // or new HttpClient();
Then, you perform your calls using the same instance of the client. The client will take a cookie from a response, will store it in the cookieStore and will send it with the next request.
[Added after the comment]
The following code works for me:
httpClient = new DefaultHttpClient();
// Create a local instance of cookie store
cookieStore = new BasicCookieStore();
// Set the store
httpClient.setCookieStore(cookieStore);

Setting and Retrieving Cookies using HttpComponents

I am trying to figure out how to set and also retrieve cookies using HttpComponents, but I can't find solid documentation, especially when it comes to setting cookies on the request. What I have seems to work, but at the same time I can't confirm that the cookies I set are being sent correctly.
I notice that the cookie that I set on the request is also in the CookieStore after calling client.execute(), but I'm not sure if that's just because I add it to the CookieStore before calling client.execute() (maybe it stays in the CookieStore without being actually sent with the request?). Is there a good way to confirm the cookie is sent?
HttpGet get = new HttpGet("http://example.com/");
DefaultHttpClient client = new DefaultHttpClient();
// set the cookies
CookieStore cookieStore = new BasicCookieStore();
BasicClientCookie cookie = new BasicClientCookie("foo", "bar");
cookie.setDomain("example.com");
cookie.setPath("/something/");
cookieStore.addCookie(cookie);
client.setCookieStore(cookieStore);
// get the cookies
HttpResponse response = client.execute(get);
List<Cookie> cookies = client.getCookieStore().getCookies();
just found the follwoing example which demonstrates the use of cookies in an login example: HttpComponents Example with Cookies
Maybe you can modify this in a way what the server responds with the content of the cookie sent, so you can eval if the cookie really was sent to the server. (You send cookie with "foo", "bar" or some randomize values and the server will respond with "bar", "foo" or something like that)

Categories

Resources