Open WebView with result from Http post - java

I having an issue from my HTTP Post.
The code I'm using are working (have tested to post data to a guestbook form and it worked).
Now what I want. I have created two EditText forms, that holds values. I have a submit button there I post this data (like the test I wrote about before), but now I want to post it into a login.php page (that in a normal browser redirects me to the member.php page).
Although I know the forms are correctly filled in and it successfully posted on the "test" site, I wanna get the response from login.php and check if the user is successfully logged in or if it failed, if succeeded -> redirect me to member.php page.
All I know is this:
HttpResponse response = httpclient.execute(httppost);
that executes the command. But how should I achieve the login check? Any further use of the response variable?

Well... your approach is not good at all. If you are going to allow user authenticate through your app, why do you want to redirect the user to a member.php page? why don't you just put the login form in a login.php file on the server and make the user browse through your site?
As user, if an app allows me to authenticate using EditTexts inside UI, I would expect to access all the content through the app instead of being redirected to a web interface.
Anyway, if you decide to continue doing it that way keep in mind that you would have to parse and process cookies manually, and inject them into the WebView (Google about the CookieManager class). That's the way how the user will really be logged-in in your web app.
Can you provide a small example of how to set it up? The stream I will get, is that a special server response for example, a successfully login?
Here you have:
public String getPostRequest(String url, String user, String pass) {
HttpClient postClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
HttpResponse response;
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("user", user));
nameValuePairs.add(new BasicNameValuePair("pass", pass));
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
response = postClient.execute(httpPost);
if(response.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
String result = convertStreamToString(instream);
instream.close();
return result; // here is a string of the result!!!
}
}
} catch (Exception e) {}
return null; // if it gets here, something wrong happens with the connection
}
private String convertStreamToString(InputStream is) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
How do you use it? Something like this:
String result = getPostRequest("http://yourpage.com/login.php", "the username", "his/her pass");
if( result.equals("OK") ){
// voila!
}
I'm here supposing that you have something like this in your PHP code:
<?php
// login logic here
if( $success ){
die("OK");
}
?>

Related

Test an outgoing HTTP request in Spring

I feel very sorry to ask that question because I am pretty sure that this was already asked. But by searching here or with google I always land at sites where REST services with incoming requests are tested.
In my case I have a method that sends a request to a server. I want to test if that request is correct. I use java and spring boot. Every time I test that, the request is send to the server. Can I intercept that?
public void buy(double price) {
final String timestamp = String.valueOf(System.currentTimeMillis());
final String amount = String.valueOf(observer.requestedAmount);
final String ressouce = GetValuesTypes.getRessource("user").get(observer.getRelatedUser);
String queryArgs = "wwww.doSomething.com/" + ressouce;
String hmac512 = HMAC512.hmac512Digest(queryArgs);
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost post = new HttpPost(GetValuesTypes.getURL());
post.addHeader("Key", GetValuesTypes.getKey());
post.addHeader("Sign", hmac512);
try {
post.setEntity(new ByteArrayEntity(queryArgs.getBytes("UTF-8")));
} catch (UnsupportedEncodingException e) {
System.out.println("Exception in run");
}
List<NameValuePair> params = new ArrayList<>();
params.add(new BasicNameValuePair("command", "order"));
params.add(new BasicNameValuePair("ressource", ressource));
params.add(new BasicNameValuePair("rate", String.valueOf(rate)));
params.add(new BasicNameValuePair("amount", amount));
params.add(new BasicNameValuePair("timestamp", timestamp));
try {
post.setEntity(new UrlEncodedFormEntity(params));
CloseableHttpResponse response = httpClient.execute(post);
HttpEntity entity = response.getEntity();
Scanner in = new Scanner(entity.getContent());
String orderNumber = "";
while (in.hasNext()) {
orderNumber = in.nextLine();
}
String[] findOrderNumber = orderNumber.split(".");
long lastOrderNumber = -1;
try {
lastOrderNumber = Long.valueOf(findOrderNumber[3]);
} catch (NumberFormatException exception) {
System.out.println("NumberFormatException");
} finally {
if (lastOrderNumber != -1) {
observer.setOrderNumber(lastOrderNumber);
}
}
in.close();
EntityUtils.consume(entity);
httpClient.close();
} catch (IOException e) {
System.out.println("Exception occured during process");
}
}
I would appreciate your help very much.
This is a typical question that are faced by all the people who are trying to write tests for their code (and this also means that there are many articles on the net about how to do it).
In this particular case, I see two ways:
if you want to write a unit test: instead of creating HttpClient, you should make it configurable, to be able to substitute it by mock in the unit tests. You can hold it as a class member or provide as a second argument to buy() method. Later, in a unit test, you need to provide a fake version of HttpClient (mock) that allows you to inspect its arguments to ensure that they're equal to expected.
if you want to write an integration test: you need to run a fake service that behaves like a real server but also allows to inspect received requests. In an integration test, you need to configure HttpClient to connect to this fake server and after that check that the server received request from a client.
How to implement this, is up to you and technologies with that you're familiar to.

Alternate for HttpClient in android?

My requirement is to upload the images to server using a Multipart request. I was able to create a Multipart Http Request using the HttpClient, which is deprecated. Is it possible to achieve the same using HttpUrlConnection? If yes, how?
Update:
Current code
{
ProgressDialog progress_dialog;
#Override
protected void onPreExecute() {
// setting progress bar to zero
progress_dialog=new ProgressDialog(CreateAlbum.this);
progress_dialog.setTitle("Loading..");
progress_dialog.show();
super.onPreExecute();
}
#Override
protected String doInBackground(Void... params) {
return uploadFile();
}
#SuppressWarnings("deprecation")
private String uploadFile() {
String responseString = null;
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://192.168.1.42:8080/test/fileUpload.php");
try
{
MultipartEntityBuilder entity = MultipartEntityBuilder.create();
entity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
File sourceFile = new File(fileUri);
// Adding file data to http body
entity.addPart("image", new FileBody(sourceFile));
// Extra parameters if you want to pass to server
entity.addPart("website",
new StringBody("www.androidhive.info"));
entity.addPart("email", new StringBody("abc#gmail.com"));
httppost.setEntity(entity);
// Making server call
HttpResponse response = httpclient.execute(httppost);
HttpEntity r_entity = response.getEntity();
int statusCode = response.getStatusLine().getStatusCode();
Log.i("RAE", "STATUS CODE IS"+statusCode);
if (statusCode == 200) {
// Server response
responseString = EntityUtils.toString(r_entity);
} else {
responseString = "Error occurred! Http Status Code: "
+ statusCode;
}
} catch (ClientProtocolException e) {
responseString = e.toString();
} catch (IOException e) {
responseString = e.toString();
}
return responseString;
}
#Override
protected void onPostExecute(String result) {
Log.e("RAE", "Response from server: " + result);
progress_dialog.dismiss();
// showing the server response in an alert dialog
Toast.makeText(getApplicationContext(), "File Uploaded", Toast.LENGTH_SHORT).show();
super.onPostExecute(result);
}
}
AndroidHttpClient has been depreciated and has no longer support from the developers. So one will have to use java's own HttpURLConnection under java.net package. Here is a demo android application which implements HttpURLConnection. Just use the following git commands and run the application in android studio
Clone the git project :-
git clone https://github.com/viper-pranish/android-tutorial.git
Download the right version of project where HttpURLConnection is implemented
git checkout 399e3d1f9624353e522faf350f38a12db635c09a
EDIT
After you understand from my code how to make a POST with HttpUrlConnection, you can edit it and integrate the following answers: Sending files using POST with HttpURLConnection
This is how I make a form-encoded POST:
// Connection
URL url = new URL("http://www.example.com");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setDoOutput(true);
conn.setDoInput(true);
// Data to be sent
DataOutputStream out = new DataOutputStream(conn.getOutputStream());
out.writeBytes(printParams(params));
out.flush();
out.close();
// Print received response
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println(inputLine);
}
in.close();
where printParams is a simple function to trasform a Map into a string like a=b&c=d:
public static String printParams(Map<String, String> params) {
StringBuffer sb = new StringBuffer();
for (Map.Entry<String, String> e: params.entrySet()) {
if (sb.length() > 0) {
sb.append("&");
}
sb.append(e.getKey()).append('=').append(e.getValue());
}
return sb.toString();
}
This link has everything you need to send a file to server using multipart. It has been updated to use the most recent http classes in android. I have tested it and use it myself today. Cheers!
http://www.androidhive.info/2014/12/android-uploading-camera-image-video-to-server-with-progress-bar/
For the nexts post show your code, the programmers need see that for give more great help, thanks. On the one hand I always use in my apps httpClient and it's the best way for me because you can configuration a specific client with handling cookies, authentication, connection management, and other features, it's simple if you have the code. If you want to see more info from this theme you can visit this links, in Class Overview part:
http://developer.android.com/reference/org/apache/http/client/HttpClient.html
http://developer.android.com/reference/java/net/HttpURLConnection.html
On the other hand, if you want to do a multiple connections with your server I recommend a parallel programming with httpClient with processes and threads can read more info here: http://developer.android.com/guide/components/processes-and-threads.html
// Last Update //
Sorry Rahul Batra I work with API 21... I noted this for next version of my app. But as the first Step I will try to use a backgroud tasks with httpURLConnection.
This post have a really great information:
http://android-developers.blogspot.com.es/2011/09/androids-http-clients.html
I hope it help you this answer!! If you need more information or anything let me know, good luck Rahul Batra.

Accessing a login api using http get method in android

I am developing an android app which uses a login api, which will allow its web users to login with their same credentials on the android device.....
the url for the api is
https://api.ecoachsolutions.com/main.php?ecoachsignin=1&server=remote&user=ecoachguest&pass=ecoachguest
which retuns a response in json
JSON object: {
status: <success or error>,
msg: <response message>,
profile: <user profile object>
}
I tried this code which I found searching on the internet but it isn't working,
private void doLogin(View view) {
//ALERT MESSAGE
_spinner.setVisibility(View.VISIBLE);
Toast.makeText(mContext, "connecting to server.... ",
Toast.LENGTH_SHORT).show();
// URLEncode user defined data
String usernameValue = username.getText().toString();
String passValue = password.getText().toString();
// Create http cliient object to send request to server
HttpClient Client = new DefaultHttpClient();
// Create URL string
String URL = "https://api.ecoachsolutions.com/main.php?ecoachsignin=1&server=remote&user="+usernameValue+"&pass="+passValue;
Log.i("httpget", URL);
try
{
String SetServerString ;
// Create Request to server and get response
HttpGet httpget = new HttpGet(URL);
ResponseHandler<String> responseHandler = new BasicResponseHandler();
SetServerString = Client.execute(httpget, responseHandler);
System.out.println(usernameValue);
System.out.println(passValue);
// Show response on activity
Toast.makeText(getBaseContext(),SetServerString,Toast.LENGTH_LONG).show();
}
catch(Exception ex)
{
Toast.makeText(getBaseContext(),"Fail",Toast.LENGTH_LONG).show();
_spinner.setVisibility(View.INVISIBLE);
}
}
will appreciate the help or the positive direction thanks :)
Change your code to get the HttpResponse like below,
String responseBody = "";
HttpResponse response = client.execute(post);
int responseCode = response.getStatusLine().getStatusCode();
Log.i("GET Response Code ",responseCode + "");
switch(responseCode) {
// Means server is responding
case 200:
HttpEntity entity = response.getEntity();
if(entity != null) {
responseBody = EntityUtils.toString(entity);
// Now you can try printing your returned string here, before you go for JSON parsing
}
break;
// Add more case statements to handle other scenarios
}
The code is simple, but if still unable to understand, don't hesitate to ask.

calling asp webservice not working as i need

I'm trying to send user and pass to asp webservice , but when getting back response get like this :
so how to fix it and get true of false
this is webservice link i have used :
http://ictfox.com/demo/Hafil_Updates/Login_Check.aspx?UserLogin=Demo&Password=Demo
02-20 19:57:23.326: D/Http Response:(4007): True<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><title></title></head><body> <form name="form1" method="post" action="Login_Check.aspx?UserLogin=Demo&Password=Demo" id="form1"><input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwULLTE2MTY2ODcyMjlkZD/N053U40olll80mNvY/Qt2aBEc" /> <div> </div> </form></body></html>
this is my full class in asyncTask android :
HttpClient httpClient = new DefaultHttpClient();
// Creating HTTP Post
HttpPost httpPost = new HttpPost(
"http://ictfox.com/demo/Hafil_Updates/Login_Check.aspx?UserLogin=Demo&Password=Demo");
// Building post parameters
// key and value pair
List<NameValuePair> nameValuePair = new ArrayList<NameValuePair>(2);
nameValuePair.add(new BasicNameValuePair("UserLogin", "Demo"));
nameValuePair.add(new BasicNameValuePair("Password",
"Demo"));
// Url Encoding the POST parameters
try {
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePair));
} catch (UnsupportedEncodingException e) {
// writing error to Log
e.printStackTrace();
}
// Making HTTP Request
try {
HttpResponse response = httpClient.execute(httpPost);
response.getEntity().getContentLength();
StringBuilder sb = new StringBuilder();
try {
BufferedReader reader =
new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
}
catch (IOException e) { e.printStackTrace(); }
catch (Exception e) { e.printStackTrace(); }
Log.d("Http Response:", sb.toString());
Is that webservice from you or a 3dr party? It seems that it not only returns the actual return value, but also some hidden HTML stuff. Check if there is an option to call the service in a way that it returns only the desired value or even better JSON. If not, just check if the return String starts with "True"
boolean success = sb.toString().toLowerCase().startsWith("true");
You would need to modify the response sent by the server, that would be the easiest thing to do. I see that you server returns True followed by some HTML code. Make your server remove the HTML
If you don't want to modify the server side code, just look in your response for the substring True.
Additionally, to get the response I use this, which may be simpler:
httpresponse = httpclient.execute(httppost);
response = EntityUtils.toString(httpresponse.getEntity());

Http 500 Internal Server Error in Android

Android code
class BirthdayTask extends AsyncTask<String, String, String>{
#Override
protected String doInBackground(String... uri) {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
String responseString = null;
try {
System.out.println(uri[0]);
response = httpclient.execute(new HttpGet(uri[0]));
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpStatus.SC_OK){
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
responseString = out.toString();
System.out.println("responseString"+responseString);
} else{
//Closes the connection.
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (ClientProtocolException e) {
//TODO Handle problems..
} catch (Exception e) {
e.printStackTrace();
}
return responseString;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
/* System.out.println(result);
System.out.println(result);
System.out.println(result);*/
}
}
#RequestMapping(value="here is my url" ,method=RequestMethod.GET)
public #ResponseBody String Test(HttpServletRequest req) {
Gson gson = new Gson();
Domain domain = (Domain)req.getSession().getAttribute("Domain");
List<UserProfile> userProfiles = userProfileManager.getUpcomingBirthday(domain.getDomainId(),15);
return gson.toJson(userProfiles);
}
Webservice
This is the webservice I am calling from browser its working fine. But when I call from Android then I get a 500 internal server error. But in server logs I see no error.
What is going wrong?
Whenever an HTTP code starts with a 5 (5xx), it means something got wrong on the server. It is not about your code here, on the android client side, but in the server side implementation.
This is webservice I am calling from broweser its woriking fine ....But when I am calling from android then 500 internal server error
This may mean the the request payload that you are sending from your android app, must be different to that when you do it from your browser. Please print your request payload and double-check everything. Additionally, it might help you also give the request headers a look.
It is hard to give an answer, but i think the session is null when you call the WS using Android. While if you call the WS using a browser the session could be mantained using cookie or sessionId i dont find any line of code that handles cookies or sessionId in some way.
IMO you shouldnt rely on session information.
Hope it helps you.
I recommend using retrofit instead of AsyncTask. It will solve the problem with a cookie.

Categories