I'm currently making an android app that makes POST requests to a tomcat server which makes a session for the user, though the sessions seem to not be working. I'm getting a new session with each request. Is there any way to keep this session or track the user another way? The code for querying the server is generally as follows:
HttpClient client = new DefaultHttpClient();
HttpPost post = HttpPostFactory.getHttpPost("AuthenticateUser");
List<NameValuePair> pairs = new ArrayList<NameValuePair>();
pairs.add(new BasicNameValuePair("option1", option1);
pairs.add(new BasicNameValuePair("option2", option2);
try {
post.setEntity(new UrlEncodedFormEntity(pairs));
HttpResponse response = client.execute(post);
StringBuilder builder = new StringBuilder();
Scanner in = new Scanner(response.getEntity().getContent());
while (in.hasNext()) {
builder.append(in.nextLine());
}
Document doc = DocumentBuilderFactory.newInstance()
.newDocumentBuilder()
.parse(MyStringUtil.toInputStream(builder.toString()));
I have full source code access to both the client and server, so a solution on either end will work.
You keep recreating your HttpClient; unless you have your own cookie store implementation that will keep cookies across instantiations or otherwise restores them, they'll keep going away.
http://hc.apache.org/httpcomponents-client-ga/tutorial/html/statemgmt.html
I believe tomcat uses a JSESSIONID to maintain sessions. This is stored as a cookie. In order to keep that same session alive, you'll need to send the cookies along with your next HttpRequest.
Related
Currently I am connecting from android to a .net WEB API using HttpClient and I have been able to do a GET and POST to read/write data. However I want to do an Update and a Delete.
I tried to do this using a POST, but it simple creates more records. Here is my code for the POST, how would I change it to do a PUT or DELETE instead?
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://mywebsite.net/api/employees/6");
try {
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(5);
nameValuePairs.add(new BasicNameValuePair("firstName", "UpdatedHello"));
nameValuePairs.add(new BasicNameValuePair("lastName", "World"));
nameValuePairs.add(new BasicNameValuePair("employee_name", "UpdatedHello World"));
nameValuePairs.add(new BasicNameValuePair("password", "xxx"));
nameValuePairs.add(new BasicNameValuePair("isActive", "1"));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
yeah! the document of httpClient http://hc.apache.org/httpclient-3.x/methods.html
You have PutMethod and DeleteMethod API for performing PUT and DELETE Http requests. The sample usage as follows as per doc
PUT Request - The put method is very simple, it takes a URL to put to and requires that the body of the request method be set to the data to upload. The body can be set with an input stream or a string.This method is generally disabled on publicly available servers because it is generally undesireable to allow clients to put new files on the server or to replace existing files.
PutMethod put = new PutMethod("http://jakarta.apache.org");
put.setRequestBody(new FileInputStream("UploadMe.gif"));
// execute the method and handle any error responses.
...
// Handle the response. Note that a successful response may not be
// 200, but may also be 201 Created, 204 No Content or any of the other
// 2xx range responses.
DELETE Request - The delete method is used by supplying a URL to delete the resource at and reading the response from the server.This method is also generally disabled on publicly available servers because it is generally undesireable to allow clients to delete files on the server.
DeleteMethod delete = new DeleteMethod("http://jakarata.apache.org");
// execute the method and handle any error responses.
...
// Ensure that if there is a response body it is read, then release the
// connection.
...
delete.releaseConnection();
Im coding a RESTful API & Android client at the same time as I go and im currently working on pulling the users profile from the server. I feel like this should definitely be a get request being that im only pulling existing data and im not adding/editing anything to my database, but I do need a user_id param to be able to query for the appropriate profile. Can I send just one tiny little variable along with my HttpGet some how or am i supposed to use a HttpPost in this situation regardless?
Android uses Apache's HTTPClient. So, copying their tutorial code:
public void sendStringTo(String remoteUrl, String myString) {
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(remoteUrl+"?string1="+myString);
HttpResponse response1 = httpclient.execute(httpGet);
// The underlying HTTP connection is still held by the response object
// to allow the response content to be streamed directly from the network socket.
// In order to ensure correct deallocation of system resources
// the user MUST either fully consume the response content or abort request
// execution by calling HttpGet#releaseConnection().
try {
System.out.println(response1.getStatusLine());
HttpEntity entity1 = response1.getEntity();
// do something useful with the response body
// and ensure it is fully consumed
EntityUtils.consume(entity1);
} finally {
httpGet.releaseConnection();
}
return;
}
GET can support adding variables/parameters. For example you could make a Url that looks like this:
http://yourwebsite.com/script.php?user_id=19898424
I have a site that I would like to log into. Once there, I would parse the code to display member data (like any other login app). I have sort of pulled this code from somewhere and I'd like to know why it's crashing. Basically, I have two login inputs, username and password. I'll take them from the user but as of now I'm just inputting random credentials for testing. At the end, I want to get it to the login page (same url once logged in) and display the HTML, for now.
Here's my code so far:
HttpClient httpClient = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(httpClient.getParams(), TIMEOUT_MS);
HttpConnectionParams.setSoTimeout(httpClient.getParams(), TIMEOUT_MS);
HttpPost httpPost = new HttpPost("login url"); // Removed for StackOverflow question
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("sid", "name"));
nameValuePairs.add(new BasicNameValuePair("pin", "pass"));
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpClient.execute(httpPost);
BufferedReader br = new BufferedReader(new InputStreamReader(response.getEntity().getContent()), 8096);
tvStatus.setText((CharSequence) br);
Are you running the POST request on the UI thread? This causes the UI to freeze and after a certain time period, the OS considers the app to be non-responsive and force closes it. Web Requests should always be an Async task
I guess this post on my blog will help you to understand, how to use AsyncTask, for downloading stuff.
Though if you tell us what is the Exception which is getting thrown up, I could've helped you more on this. To see the Exception, open the LogCat,identify the error text which will be in red, copy the whole red text and paste it into your question.
I am implementing a login feature in Android.
Does android have anything like sessions or cookies? How should I 'remember' that the user is loged in? Obviously I don't want to ask for the password every time my application is used!
Should I hash the password before sending it to the server? I have a table in my database with a user and password column. When I want to check the login, should I send the password hashed to the server like login.php?u=sled&p=34819d7beeabb9260a5c854bc85b3e44, or just plain text like login.php?u=sled&p=mypassword and hash it on the server before I perform the authentication?
Does android have anything like sessions or cookies?
Yes. There are two alternatives.
Option #1:
You can use CookieManager to set your cookie.
Option #2:
The other alternative (I'm using this alternative in one of my applications) is to grab your cookie after you've sent your username and password to the server (e.g. via HttpPost or HttpGet). In your question you're using $_GET style of your login authentication, so my sample code will be using HttpGet.
Sample code using HttpGet:
HttpParams httpParams = new BasicHttpParams();
// It's always good to set how long they should try to connect. In this
// this example, five seconds.
HttpConnectionParams.setConnectionTimeout(httpParams, 5000);
HttpConnectionParams.setSoTimeout(httpParams, 5000);
DefaultHttpClient postClient = new DefaultHttpClient(httpParams);
// Your url using $_GET style.
final String url = "www.yourwebsite.com/login.php?u=myusername&p=mypassword";
HttpGet httpGet = new HttpGet(url);
HttpResponse response;
try {
// Execute your HttpGet against the server and catch the response to our
// HttpResponse.
response = postClient.execute(httpGet);
// Check if everything went well.
if(response.getStatusLine().getStatusCode() == 200) {
// If so, grab the entity.
HttpEntity entity = response.getEntity();
// If entity isn't null, grab the CookieStore from the response.
if (entity != null) {
CookieStore cookies = postClient.getCookieStore();
// Do some more stuff, this should probably be a method where you're
// returning the CookieStore.
}
}
} catch (Exception e) {
}
Now when you have your CookieStore; grab a list of cookies from it and after that you can use Cookie to determine the name, domain, value etc...
Next time you're trying to access "locked" content of your website; set a cookie to your HttpURLConnection from your Cookie information:
URL url = new URL("www.yourwebsite.com/lockedcontent.php");
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setInstanceFollowRedirects(false);
// "Host" and "Cookie" are fields in the HTTP response. Use WireShark
// via your computer to determine correct header names.
httpURLConnection.setRequestProperty("Host", domainOfYourCookie);
httpURLConnection.setRequestProperty("Cookie", valueOfYourCookie);
final int responseCode = httpURLConnection.getResponseCode();
// And get the content...
Should I hash the password before sending it to the server?
Depends on how your system is designed. You must have correct information when sending it to your server. This also depends on how you're hashing your information in your .php file.
How should I 'remember' that the user is loged in?
Store the information in a SharedPreferences or something. Like I said earlier, you can hash it if your login system is correctly designed - this depends on how you're hashing it in your .php file.
I am able to use the example here: http://www.androidsnippets.org/snippets/36/index.html and successfully get the "HTTP/1.1 OK" response for a webesite I am sending the HttpPost along with the user credentials. However, I am unable to use an HttpGet to further browse other pages on this site.
Can anyone please let me know, what's going wrong. I am sorry - I am very new to Java.
My guess would be that when the website gets the Post and logs the user in, it sets cookies on the response to indicate that the user is logged in, and then requires those cookies on subsequent Get's.
You will need to do something like the following (this is borrowed from a bigger app so may not compile right out of the box)
DefaultHttpClient mHttpClient = new DefaultHttpClient();
BasicHttpContext mHttpContext = new BasicHttpContext();
CookieStore mCookieStore = new BasicCookieStore();
mHttpContext.setAttribute(ClientContext.COOKIE_STORE, mCookieStore);
This sets up a cookie store within the HTTP context, and you then use that context on Get's and Post's. For example...
HttpResponse response = mHttpClient.execute(mRequest, mHttpContext);
Under the covers the HTTP client will store cookies from responses, and add them to requests.