download a file using apache http - java

I was trying to download a zip file from a page which requries username/password to access ( html form based authentication). I am using apache http library for it.
Earlier I had worked on something very similar, that page required just password to download the file.
Here is my code
DefaultHttpClient httpclient = new DefaultHttpClient();
httpclient.setRedirectStrategy(new DefaultRedirectStrategy() {
public URI lastRedirectedUri;
public boolean isRedirected(HttpRequest request,
HttpResponse response,
HttpContext context) {
boolean isRedirect = false;
try {
isRedirect =
super.isRedirected(request, response,
context);
} catch (org.apache.http.ProtocolException e) {
e.printStackTrace();
}
if (!isRedirect) {
int responseCode =
response.getStatusLine().getStatusCode();
if (responseCode == 301 ||
responseCode == 302) {
System.out.println("the original response code is" + responseCode);
return true;
}
}
return isRedirect;
}
// public URI getLocationURI(HttpResponse response, HttpContext context)
// throws ProtocolException {
//
// lastRedirectedUri = super.getLocationURI(request , response, context);
//
// return lastRedirectedUri;
// }
});
List<NameValuePair> formparams = new ArrayList<NameValuePair>();
// formparams.add(new BasicNameValuePair("password", arg[1]));
formparams.add(new BasicNameValuePair("password", "*****"));
formparams.add(new BasicNameValuePair("email", "****"));
UrlEncodedFormEntity entity1 =
new UrlEncodedFormEntity(formparams, "UTF-8");
HttpPost httppost =
new HttpPost("https://*************************/l/?next=/s/48750/d/");
// new HttpPost(arg[0]);
httppost.setEntity(entity1);
HttpContext localContext = new BasicHttpContext();
CookieStore cookieStore = new BasicCookieStore();
localContext.setAttribute(ClientContextConfigurer.COOKIE_STORE, cookieStore);
HttpResponse response = httpclient.execute(httppost, localContext);
HttpHost target =
(HttpHost)localContext.getAttribute(ExecutionContext.HTTP_TARGET_HOST);
System.out.println("Final target: " + target);
System.out.println(response.getProtocolVersion());
System.out.println(response.getStatusLine().getStatusCode());
System.out.println(response.getStatusLine().getReasonPhrase());
System.out.println(response.getStatusLine().toString());
HttpEntity entity = response.getEntity();
if (entity != null) {
FileOutputStream fos =
new java.io.FileOutputStream("download.zip");
entity.writeTo(fos);
fos.close();
}
if you open the url provided in the code you will find the form has two parameters by the name email and password , and I have supplied them as formparams ( values commented in the code above ).
Any help will be greatly appreciated.

Try using BasicAuthentication.
http://hc.apache.org/httpclient-3.x/authentication.html#Authentication_Schemes
http://hc.apache.org/httpclient-3.x/authentication.html#Examples

Related

Can't login with apache HttpClient 4.5.1

I'm trying to login to a website on which I want to download and parse the HTML page right after the login. For testing I'm using the following JUnit test:
#Test
public void testLogin() throws IOException, URISyntaxException {
CloseableHttpClient httpClient = null;
CloseableHttpResponse loginResponse = null;
CloseableHttpResponse getDataResponse = null;
try {
CookieStore cookieStore = new BasicCookieStore();
RequestConfig globalConfig = RequestConfig.custom()
.setCookieSpec(CookieSpecs.STANDARD)
.build();
HttpClientContext context = HttpClientContext.create();
context.setCookieStore(cookieStore);
httpClient = HttpClients.custom()
.setDefaultRequestConfig(globalConfig)
.setDefaultCookieStore(cookieStore)
.setRedirectStrategy(new LaxRedirectStrategy())
.build();
List<NameValuePair> formparams = new ArrayList<>();
formparams.add(new BasicNameValuePair("user", "username"));
formparams.add(new BasicNameValuePair("pass", "password"));
formparams.add(new BasicNameValuePair("submit", "Login"));
formparams.add(new BasicNameValuePair("logintype", "login"));
formparams.add(new BasicNameValuePair("pid", "1"));
formparams.add(new BasicNameValuePair("redirect_url", ""));
formparams.add(new BasicNameValuePair("tx_felogin_pil[noredirect]", "0"));
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams);
HttpPost login = new HttpPost("https://localhost/");
login.setEntity(entity);
loginResponse = httpClient.execute(login, context);
List<Cookie> cookies = cookieStore.getCookies();
if (cookies.isEmpty()) {
System.out.println("None");
} else {
for (int i = 0; i < cookies.size(); i++) {
System.out.println("- " + cookies.get(i).toString());
}
}
loginResponse.getEntity().writeTo(System.out);
HttpGet getData = new HttpGet("https://localhost/");
getDataResponse = httpClient.execute(getData, context);
getDataResponse.getEntity().writeTo(System.out);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (loginResponse != null) {
loginResponse.close();
}
if (getDataResponse != null) {
getDataResponse.close();
}
if (httpClient != null) {
httpClient.close();
}
}
After executing the login request there are the needed sessions in the CookieStore but the entity of the response still contains the HTML of the login page. The problem remains after executing the getData request. Still the login page content in the HttpResponse entity.
With the following curl command it is working:
curl --data "user=username&pass=password" https://localhost/
Do you have any idea what is wrong?
Might need to use HttpPost instead of HttpGet

com.sun.net.httpserver doesn't work with org.apache.http.client

I make two requests from one client to the server and client hangs on second execute of method httpclient.execute(httpPost); if I create new client for each request everything is OK. If I make POST to google(for example) everything is OK. What's the problem?
Server:
public static void main(String[] args) throws IOException {
HttpServer server = HttpServer.create(new InetSocketAddress("localhost", 8080),2);
server.setExecutor(Executors.newFixedThreadPool(5));
HttpContext context = server.createContext("/", new GlobalHandler());
context.getFilters().add(new GlobalFilter());
server.createContext("/setup.exe", new GetFileHandler());
server.start();
}
private static class GlobalHandler implements HttpHandler {
#Override
public void handle(HttpExchange t) throws IOException {
Headers headers = t.getRequestHeaders();
System.out.println(headers.entrySet());
System.out.println(t.getHttpContext());
System.out.println(t.getRequestURI());
System.out.println(t.getProtocol());
System.out.println(t.getRequestMethod());
String resp = "Hello";
if (Objects.equals(t.getRequestMethod(), "POST")) {
System.out.println("POST");
Map params = (Map) t.getAttribute("parameters");
resp = params.toString();
System.out.println(params);
}
byte[] bytesToWrite = resp.getBytes("UTF-8");
t.sendResponseHeaders(200, bytesToWrite.length);
OutputStream os = t.getResponseBody();
os.write(bytesToWrite);
}
}
Client:
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(1 * 1000).build();
httpclient = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).build();
for(int i= 0;i<2;i++) {
HttpPost httpPost = new HttpPost("http://google.com");
httpPost.addHeader("Connection","keep-alive");
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
nvps.add(new BasicNameValuePair("username", "вг"));
nvps.add(new BasicNameValuePair("password", "аб"));
httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
CloseableHttpResponse response2 = httpclient.execute(httpPost);
try {
System.out.println(response2.getStatusLine());
HttpEntity entity2 = response2.getEntity();
if(entity2.getContentLength() >0) {
byte[] content = new byte[(int) entity2.getContentLength()];
entity2.getContent().read(content);
System.out.println(new String(content, "UTF-8"));
}
EntityUtils.consume(entity2);
} finally {
response2.close();
}
}
httpclient.close();

sending a post request apache and java

I have this code block that sends a post request to one of my localhost ports:
public String request(String name){
String responseString = null;
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("userName", name));
params.add(new BasicNameValuePair("passWord","123455"));
HttpPost post = new HttpPost("http://localhost:2332/getData/postData");
post.addHeader("Content-Type", "application/x-www-form-urlencoded");
post.setEntity(new StringEntity(URLEncodedUtils.format(params,"UTF-8"), HTTP.UTF_8));
responseString = execute(post,params.toString());
return responseString;
}
public String execute(HttpRequestBase requestBase, String params){
HttpClient httpClient = new DefaultHttpClient();
HttpResponse response = null;
String responseString = "";
try {
LOG.info("Request Method:{}",requestBase.getMethod());
LOG.info("Request Parameters:{}",params);
response = httpClient.execute(requestBase);
HttpEntity entity = response.getEntity();
responseString = EntityUtils.toString(entity);
} catch (IOException e) {
e.printStackTrace();
}
return responseString;
}
I think that this code block should work because I used a tutorial as a reference but whenever I run my application the value of responseString is null or the application doesn't show me any results. Is there something wrong with my code?

Getting "Invalid JSON primitive" error while trying to get data from WebService

I'm working on an android app and I want to get some data from a WebService. I'm using this code to get JSON data from the WebService.
TextView textv=(TextView) findViewById(R.id.textv);
try {
HttpClient client = new DefaultHttpClient();
String URL = "http://server/WebService.asmx/Get_ActiveFair";
HttpPost post = new HttpPost(URL);
post.setHeader("Content-Type", "application/json; charset=utf-8");
HttpResponse responsePost = client.execute(post);
HttpEntity resEntityPost = responsePost.getEntity();
if (resEntityPost != null)
{
String response=EntityUtils.toString(resEntityPost);
Log.e("XXX",response);
textv.setText(response);
}
} catch (Exception e) {
e.printStackTrace();
textv.setText(e.toString());
Log.e("error!!",e.toString());
}
It works correctly an I get the data like this:
{
"d": "{\"Id\":2,\"Name\":\"Fair Name \",\"IsActive\":true,\"Date_Start\":\"\\/Date(1383343200000)\\/\",\"Date_End\":\"\\/Date(1384034400000)\\/\",\"Url_Map\":null,\"Details\":\"Fair Details \",\"Address\":\"FairAdress \",\"VisitingInfo\":\"Fair Visiting Info\",\"Contact\":null,\"Transportation\":\" Fair Transportation Info \"}"
}
But when I want to use another method in the webservice which needs to get FairId I get the result:
{
"Message": "Invalid JSON primitive: FairId.",
"StackTrace": " at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializePrimitiveObject()\r\n at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeInternal(Int32 depth)\r\n at System.Web.Script.Serialization.JavaScriptObjectDeserializer.BasicDeserialize(String input, Int32 depthLimit, JavaScriptSerializer serializer)\r\n at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize[T](String input)\r\n at System.Web.Script.Services.RestHandler.ExecuteWebServiceCall(HttpContext context, WebServiceMethodData methodData)",
"ExceptionType": "System.ArgumentException"
}
And here is my code to run the Get_EventList method:
TextView textv=(TextView) findViewById(R.id.textv);
try {
HttpClient client = new DefaultHttpClient();
String URL = "http://server/WebService.asmx/Get_EventList";
HttpPost post = new HttpPost(URL);
List<NameValuePair> postParameters;
postParameters = new ArrayList<NameValuePair>();
postParameters.add(new BasicNameValuePair("FairId", "2"));
post.setEntity(new UrlEncodedFormEntity(postParameters));
post.setHeader("Content-Type", "application/json; charset=utf-8");
HttpResponse responsePost = client.execute(post);
HttpEntity resEntityPost = responsePost.getEntity();
if (resEntityPost != null)
{
String response=EntityUtils.toString(resEntityPost);
Log.e("XXX",response);
textv.setText(response);
}
} catch (Exception e) {
e.printStackTrace();
textv.setText(e.toString());
Log.e("hata!!",e.toString());
}
What can be the problem? How can I solve it?
I solve the problem by sending FairId to WebService with JSONObject. Here is my new code:
TextView textv=(TextView) findViewById(R.id.textv);
try {
HttpClient client = new DefaultHttpClient();
String URL = "http://server/WebService.asmx/Get_EventList";
HttpPost post = new HttpPost(URL);
JSONObject json = new JSONObject();
json.put("FairId", "2");
StringEntity se = new StringEntity( json.toString());
se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
post.setEntity(se);
HttpResponse responsePost = client.execute(post);
HttpEntity resEntityPost = responsePost.getEntity();
if (resEntityPost != null)
{
String response=EntityUtils.toString(resEntityPost);
Log.e("XXX",response);
textv.setText(response);
}
} catch (Exception e) {
e.printStackTrace();
textv.setText(e.toString());
Log.e("hata!!",e.toString());
}

Httpclient 4, error 302. How to redirect?

I want to access one site that first requires an (tomcat server) authentication and then log in with a POST request and keep that user to see the site's pages. I use Httpclient 4.0.1
The first authentication works fine but not the logon that always complains about this error: "302 Moved Temporarily"
I keep cookies & I keep a context and yet nothing. Actually, it seems that the logon works, because if I write incorrect parameters or user||password, I see the login page. So I guess what doesn't work is the automatic redirection.
Following my code, which always throws the IOException, 302:
DefaultHttpClient httpclient = new DefaultHttpClient();
CookieStore cookieStore = new BasicCookieStore();
httpclient.getParams().setParameter(
ClientPNames.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY);
HttpContext context = new BasicHttpContext();
context.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
//ResponseHandler<String> responseHandler = new BasicResponseHandler();
Credentials testsystemCreds = new UsernamePasswordCredentials(TESTSYSTEM_USER, TESTSYSTEM_PASS);
httpclient.getCredentialsProvider().setCredentials(
new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT),
testsystemCreds);
HttpPost postRequest = new HttpPost(cms + "/login");
List<NameValuePair> formparams = new ArrayList<NameValuePair>();
formparams.add(new BasicNameValuePair("pUserId", user));
formparams.add(new BasicNameValuePair("pPassword", pass));
postRequest.setEntity(new UrlEncodedFormEntity(formparams, "UTF-8"));
HttpResponse response = httpclient.execute(postRequest, context);
System.out.println(response);
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK)
throw new IOException(response.getStatusLine().toString());
HttpUriRequest currentReq = (HttpUriRequest) context.getAttribute(
ExecutionContext.HTTP_REQUEST);
HttpHost currentHost = (HttpHost) context.getAttribute(
ExecutionContext.HTTP_TARGET_HOST);
String currentUrl = currentHost.toURI() + currentReq.getURI();
System.out.println(currentUrl);
HttpEntity entity = response.getEntity();
if (entity != null) {
long len = entity.getContentLength();
if (len != -1 && len < 2048) {
System.out.println(EntityUtils.toString(entity));
} else {
// Stream content out
}
}
For 4.1 version:
DefaultHttpClient httpclient = new DefaultHttpClient();
httpclient.setRedirectStrategy(new DefaultRedirectStrategy() {
public boolean isRedirected(HttpRequest request, HttpResponse response, HttpContext context) {
boolean isRedirect=false;
try {
isRedirect = super.isRedirected(request, response, context);
} catch (ProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (!isRedirect) {
int responseCode = response.getStatusLine().getStatusCode();
if (responseCode == 301 || responseCode == 302) {
return true;
}
}
return isRedirect;
}
});
For HttpClient 4.3.x :
HttpClient httpClient = HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategy()).build();
In later versions of HttpCLient (4.1+), you can just do this:
DefaultHttpClient client = new DefaultHttpClient()
client.setRedirectStrategy(new LaxRedirectStrategy())
LaxRedirectStrategy will automatically redirect HEAD, GET, and POST requests. For a stricter implementation, use DefaultRedirectStrategy.
You have to implement custom redirection handler that will indicate that response to POST is a redirection. This can be done by overriding isRedirectRequested() method as shown below.
DefaultHttpClient client = new DefaultHttpClient();
client.setRedirectHandler(new DefaultRedirectHandler() {
#Override
public boolean isRedirectRequested(HttpResponse response, HttpContext context) {
boolean isRedirect = super.isRedirectRequested(response, context);
if (!isRedirect) {
int responseCode = response.getStatusLine().getStatusCode();
if (responseCode == 301 || responseCode == 302) {
return true;
}
}
return isRedirect;
}
});
In later version of HttpClient, the class name is DefaultRedirectStrategy, but similar solution can be used there.
httpclient.setRedirectHandler(new DefaultRedirectHandler());
See HttpClient Javadoc
Redirects are not handled automatically by HttpClient 4.1 for other methods than GET and PUT.
Extend the DefaultRedirectStrategy class and override the methods.
#Override
protected URI createLocationURI(String arg0) throws ProtocolException {
// TODO Auto-generated method stub
return super.createLocationURI(arg0);
}
#Override
protected boolean isRedirectable(String arg0) {
// TODO Auto-generated method stub
return true;
}
#Override
public URI getLocationURI(HttpRequest arg0, HttpResponse arg1,
HttpContext arg2) throws ProtocolException {
// TODO Auto-generated method stub
return super.getLocationURI(arg0, arg1, arg2);
}
#Override
public HttpUriRequest getRedirect(HttpRequest request,
HttpResponse response, HttpContext context)
throws ProtocolException {
URI uri = getLocationURI(request, response, context);
String method = request.getRequestLine().getMethod();
if (method.equalsIgnoreCase(HttpHead.METHOD_NAME)) {
return new HttpHead(uri);
} else {
return new HttpPost(uri);
}
}
#Override
public boolean isRedirected(HttpRequest request, HttpResponse response,
HttpContext context) throws ProtocolException {
// TODO Auto-generated method stub
return super.isRedirected(request, response, context);
}
in this case isRedirectable method will always return true and getRedirect method will return post request in place of get request.

Categories