In Java, if I want to send data to form on the server, where form type is:
<form method="post" id="form1" name="form1" action="">
<div id="login" class="box">
<div class="header">Log in</div>
<div class="content">
<label for="txtUser">User:</label>
<input id="txtUser" name="txtUser" type="text" size="13" value="" />
<label for="txtPassword">Password:</label>
<input id="txtPassword" name="txtPassword" type="password" size="13" value="" />
<input id="BLogin" name="BLogin" type="submit" value="Log in" />
</div>
<div class="footer">
<input type="checkbox" id="chkSave" name="chkSave" /> <label for="chkSave">Save account</label>
</div>
</div>
</form>
in this case I must use HttpPost method, since the form accepts the method "post" as it is stated in the form definition(initialization):
<form method="**post**" id="form1" name="form1" action="">
In my example(android solution) i am using the
__VIEWSTATE
__EVENTTARGET
__EVENTARGUMENT
ctl00$tbUsername
ctl00$tbPwd
ctl00$chkRememberLogin
ctl00$cmdLogin
values, since they are the once that are required by the server to make the post. Where do I find what is required by the server in the case when you have not programmed the server? I am using the WireShark software to see all the incomming responses or outgoing requests between the client and the server, just use the http filter to see only the http transactions. Then use any browser to login in the usual way as you do it online and then in WireShark you will see all the requests and responses between your browser and server. Find the one you are interested in by the known IP address or the host address and then copy the readable bytes which you find if you click the right button on any of the transactions. So when you do that, you will find how your request to the server must look like and which values are needed.
Back to coding(java):
public HttpResponse httpPost1(String viewstateValue, String url, String username, String password)
throws ConnectTimeoutException {
try {
// --------post
HttpPost httppost = new HttpPost(url);
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("__VIEWSTATE",
viewstateValue));
nameValuePairs.add(new BasicNameValuePair("__EVENTTARGET", ""));
nameValuePairs
.add(new BasicNameValuePair("__EVENTARGUMENT", ""));
nameValuePairs.add(new BasicNameValuePair("ctl00$tbUsername",
username));
nameValuePairs.add(new BasicNameValuePair("ctl00$tbPwd", password));
nameValuePairs.add(new BasicNameValuePair(
"ctl00$chkRememberLogin", "0"));
nameValuePairs.add(new BasicNameValuePair("ctl00$cmdLogin",
"Login"));
// nameValuePairs.add(new
// BasicNameValuePair("ctl00$cmdForgetMe",
// "Forget Me"));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
response = client.execute(httppost);
String responseHtml = EntityUtils.toString(response
.getEntity());
// System.out.println(responseHtml);
// System.out.println(response1.getStatusLine());
} catch (ClientProtocolException e) {
} catch (IOException e) {
}
return response;
}
Here i post the values to the URL which i know in advance.
You might add headers using
httppost.addHeader("Referer",
"http://website/login.asp");
or time-out value to the request
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
int timeoutConnection = 5000;
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters,
timeoutConnection);
In this case it is better to catch the exceptions if the timeout occured and make the request again, as it is advised to do in the HttpClient documentation.
HttpClient follows redirects by default, but it is possible to catch everytime the redirect occurs by using:
private RedirectHandler customRedirectHandler;
........
(maybe constructor..)
client.setRedirectHandler(customRedirectHandler);
........
class CustomRedirectHandler extends DefaultRedirectHandler {
@Override
public boolean isRedirectRequested(HttpResponse response,
HttpContext context) {
// System.out.println("isRedirectRequested");
return true;
}
@Override
public URI getLocationURI(HttpResponse response, HttpContext context)
throws ProtocolException {
String location = response.getLastHeader("Location").getValue();
if (location.contains("Login")) {
// System.out.println("Login needed");
} else {
// System.out.println("No login required");
}
URI redirectURI = null;
try {
redirectURI = new URI(location);
} catch (URISyntaxException e) {
}
return redirectURI;
}
}
}
and then after doing everything that you need with the client you might release your clients connection:
public void shutDownClient() {
client.getConnectionManager().shutdown();
}
This is an example of the HttpClient, do not forget that you might also use the UrlConnection, here are differences shown:
http://www.innovation.ch/java/HTTPClient/urlcon_vs_httpclient.html
So it depends what you prefer to use and what is more appropriate for your project.
P.S. This POST solution is applied to my project, but it may not work for yours.. Use Wireshark first and then see what kind of requests must be sent to the server. In my case it was like viewstate=sdsgdgdfd323&username=dsfngkjfdg&password=dsfsdfsfs..... but i know that there might be others.
See Question&Answers more detail:
os