I'm making an app which let people login, sign in, sign up, write something and save it to database.
So I decided to chose Restful Api with Slim Framework. I publish it in my host and test by extension of google chrome call Advanced Rest Client. Everything like login ,signin, sign up, wite something, update it, delete it.. work fine.
For example:
I log in with information:
email: stark#gmail.com
password: abc
then the result is something like that.
{
error: false
name: "Kien"
email: "nguyenkien1402#yahoo.com"
apiKey: "fc2aee103c861026cb53fd8920b10adc"
createdAt: "2015-06-24 00:28:01"
}
But when I used it in my android app. I cannot connect and get information by JSON.
Please tell my how to solve this problem.
Thank you.
Sorry about my english, it's not native english.
To connect to the restful API, the following steps you have to do
give internet access
have to do http connection
have to to take stream input
Give Internet Access
to give internet access to the app we have to add this piece of code in the file " AndroidManifest.xml"
<uses-permission android:name="android.permission.INTERNET"/>
To do the second and third step we have to create a new java class as when we are connecting to the restful API, it will run in the background and MainActivity does not allow the background task.
Let say we create a new java class "fetchData" to get data from the API.
to do the remaining task we have to use this piece of code
URL url = new URL(API ADDRESS);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
InputStream inputStream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
now you get the JSON file using the "Bufferedreader.readLine()"
then the class file looks like this
import android.os.AsyncTask;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class fetchData extends AsyncTask<Void,Void,Void> {
String data ="";
String dataParsed = "";
String singleParsed ="";
#Override
protected Void doInBackground(Void... voids) {
try {
URL url = new URL("https://api.myjson.com/bins/k3p10");
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
InputStream inputStream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line = "";
while(line != null){
line = bufferedReader.readLine();
data = data + line;
}
JSONArray JA = new JSONArray(data);
for(int i =0 ;i <JA.length(); i++){
JSONObject JO = (JSONObject) JA.get(i);
singleParsed = "Name:" + JO.get("name") + "\n"+
"email:" + JO.get("email") + "\n"+
"Error:" + JO.get("error") + "\n";
dataParsed = dataParsed + singleParsed +"\n" ;
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
}
}
from the JSON array, you can extract everything from the JSON you get from the API. then you can use the information as per your requirement.
If your url is generating json response, then you have to read that.
public static String sendGet(String url) throws Exception {
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
// optional default is GET
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
System.out.println("\nSending 'GET' request to URL : " + url);
System.out.println("Response Code : " + responseCode);
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
return response.toString(); //here is your response which is in string type, but remember that the format is json.
}
Then convert your response to json:
JsonObject obj = new JsonObject(response);
I solved it.
It up to my class about CRUD JSON.
Thank you.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
I am asking this because I am beginner in android development.
I am doing a core-banking application, so I used JSON Parser class to connect with REST Web-Service,
JSONParser Class is,
package com.anvinsolutions.digicob_custmate;
import android.util.Log;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
public class JSONParser {
String charset = "UTF-8";
HttpURLConnection conn;
DataOutputStream wr;
StringBuilder result;// = new StringBuilder();
URL urlObj;
JSONObject jObj = null;
StringBuilder sbParams;
String paramsString;
public JSONObject makeHttpRequest(String url, String method,
HashMap<String, String> params) {
sbParams = new StringBuilder();
int i = 0;
for (String key : params.keySet()) {
try {
if (i != 0){
sbParams.append("&");
}
sbParams.append(key).append("=")
.append(URLEncoder.encode(params.get(key), charset));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
i++;
}
if (method.equals("POST")) {
// request method is POST
try {
urlObj = new URL(url);
conn = (HttpURLConnection) urlObj.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Accept-Charset", charset);
conn.setReadTimeout(10000);
conn.setConnectTimeout(15000);
conn.connect();
paramsString = sbParams.toString();
wr = new DataOutputStream(conn.getOutputStream());
wr.writeBytes(paramsString);
wr.flush();
wr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
else if(method.equals("GET")){
// request method is GET
if (sbParams.length() != 0) {
url += "?" + sbParams.toString();
}
try {
urlObj = new URL(url);
conn = (HttpURLConnection) urlObj.openConnection();
conn.setDoOutput(false);
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept-Charset", charset);
conn.setConnectTimeout(15000);
conn.connect();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
//Receive the response from the server
InputStream in = new BufferedInputStream(conn.getInputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
result = new StringBuilder(); // add this line
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
Log.d("JSON Parser", "result: " + result.toString());
} catch (IOException e) {
e.printStackTrace();
}
conn.disconnect();
// try parse the string to a JSON object
try {
jObj = new JSONObject(result.toString());
} catch (Exception e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
// return JSON Object
return jObj;
}
}
and i am confused if this method have any problem with Security,performance?
i didn't try any Libraries till now, i just used this JSONParaser Class. i think its easy to work with a JSONParser Class..
WHICH ONE TO USE?
thank you in advance! ;)
You never use JSonParser class to connect to a Web service. From your code, looks like you are using Vanilla HttpURLConnection class for connecting to service and using the JSonParser class to parse the result which is good and simple if you only have a couple of web requests to make in your application.
However since you said, it's banking application, you might have to think about scalability, multiple requests and stuffs like that. You could well try to handle them by yourself but the suggested way would be to use one of the tried and tested network libraries available for Android. Retrofit and Volley are two such and there are many more. The choice of the library to use is based on your use cases.
#AJay has already pointed to a page for comparison. Have a look.
Onto your next thing, about the parsing, performance is one of the key factors. Have a look at the below link for the options you have - http://blog.takipi.com/the-ultimate-json-library-json-simple-vs-gson-vs-jackson-vs-json/
I would say GSon is pretty good among all. We use it extensively in our in-house products.
You can use GsonParser by Google.https://github.com/google/gson
Hello you can use any of these 3 libraries they both are equally good in performance. Check this link, it will help you. Happy learning.
Comparison of Android networking libraries: OkHTTP, Retrofit, and Volley
If you have a deal with REST service, the easiest way is to use Retrofit library: https://square.github.io/retrofit/
With Retrofit you do not need to implement http calls and it automatically parses/creates json.
If you need more flexibility, I suggest using OkHttp library http://square.github.io/okhttp/, which is much simpler than pure HttpUrlConnection in combination with Gson lib https://github.com/google/gson for json parsing/creating.
Is there any way to implement NTLM Authentication with HttpURLConnection? Currently I have implemented it with DefaultHttpClient and JCIFSEngine for the authentication scheme. ( My inspiration was : Android: NTLM Authentication, ksoap, and persistent connections)
But since Android 6 Apache HTTP Client Removal, I was looking for a solution besides adding useLibrary 'org.apache.http.legacy' in app gradle file, cause I want to improve my code using HttpURLConnection class instead. As documentation says, this API is more efficient because it reduces network usage through transparent compression and response caching, and minimizes power consumption.
HttpURLConnection can work with NTLM only if you add library jcifs.
This example works with latest jcifs-1.3.18 :
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;
import org.apache.http.impl.auth.NTLMEngineException;
public class TestNTLMConnection {
public static void main(String[] args) throws UnknownHostException, IOException, NTLMEngineException {
// Method 1 : authentication in URL
jcifs.Config.registerSmbURLHandler();
URL urlRequest = new URL("http://domain%5Cuser:pass#127.0.0.1/");
// or Method 2 : authentication via System.setProperty()
// System.setProperty("http.auth.ntlm.domain", "domain");
// System.setProperty("jcifs.smb.client.domain", "domain");
// System.setProperty("jcifs.smb.client.username", "user");
// System.setProperty("jcifs.smb.client.password", "pass");
// Not verified // System.setProperty("jcifs.netbios.hostname", "host");
// System.setProperty("java.protocol.handler.pkgs", "jcifs");
// URL urlRequest = new URL("http://127.0.0.1:8180/simulate_get.php");
HttpURLConnection conn = (HttpURLConnection) urlRequest.openConnection();
StringBuilder response = new StringBuilder();
try {
InputStream stream = conn.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(stream));
String str = "";
while ((str = in.readLine()) != null) {
response.append(str);
}
in.close();
System.out.println(response);
} catch(IOException err) {
System.out.println(err);
} finally {
Map<String, String> msgResponse = new HashMap<String, String>();
for (int i = 0;; i++) {
String headerName = conn.getHeaderFieldKey(i);
String headerValue = conn.getHeaderField(i);
if (headerName == null && headerValue == null) {
break;
}
msgResponse.put(headerName == null ? "Method" : headerName, headerValue);
}
System.out.println(msgResponse);
}
}
}
Warning: jcifs ignores the connectTimeout and readTimeout you define with the library, it's the reason why the connection takes ages to break when the host is not responding. Use the code I describe in this SO thread to avoid this bug.
I have 2 TextViews in my layout with id's (matricula, nome) and i need get this values from this json request.
I have difficults in both make json request as in get values, here is an example how would i do in php and jquery:
PHP
$alunos = json_decode("let's pretend json data is here");
echo "Matricula: " . $alunos['Aluno']['matricula'];
echo "Nome: " . $alunos['Aluno']['nome'];
Jquery
var alunos = $.parseJSON("let's pretend json data is here");
console.log("Matricula: " + alunos.aluno.matricula);
console.log("Nome: " + alunos.aluno.nome);
To help:
Aluno = Student
Matricula = Student id
Nome = name
I read some answers here about parsing json but i admit it, its hard to understand.
It is also easy in Java (I left out all error handling to focus on the main flow, please add that yourself):
import org.json.JSONObject;
import java.net.URL;
import java.net.HttpURLConnection;
import java.io.InputStream;
import java.io.InputStreamReader;
...
private String readString(Reader r) throws IOException {
char[] buffer = new char[4096];
StringBuilder sb = new StringBuilder(1024);
int len;
while ((len = r.read(buffer)) > 0) {
sb.append(buffer, 0, len);
}
return sb.toString();
}
...
// fetch the content from the URL
URL url = new URL("http://..."); // add URL here
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
InputStreamReader in = new InputStreamReader(conn.getInputStream(), "UTF-8");
String jsonString = readString(in);
in.close();
conn.disconnect();
// parse it and extract values
JSONObject student = new JSONObject(jsonString);
String id = student.getJSONObject("Aluno").getString("matricula");
String name = student.getJSONObject("Aluno").getString("nome");
For details please see the documentation.
I am working on an Android web server.When i go to localhost:8080 on the emulator browser, it serves a page/form with a password field. On successful verification of the password, I would like to redirect the user to the success/failure page.What would be the best way to read the incoming http post request and parse the password field for verification?Any pointers in the right direction would be greatly appreciated. I have a handler for the url to which the form is submitted. The code for the handler is:
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import org.apache.http.HttpEntity;
import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.entity.ContentProducer;
import org.apache.http.entity.EntityTemplate;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.HttpRequestHandler;
import android.content.Context;
public class LoginHandler implements HttpRequestHandler {
private Context context = null;
public LoginHandler(Context context) {
this.context = context;
}
#Override
public void handle(final HttpRequest request, HttpResponse response,
HttpContext httpcontext) throws HttpException, IOException {
HttpEntity entity = new EntityTemplate(new ContentProducer() {
public void writeTo(final OutputStream outstream) throws IOException {
String resp = null;
OutputStreamWriter writer = new OutputStreamWriter(outstream, "UTF-8");
if(validatePassword()==true){
resp ="<html><head></head><body><h1>Home<h1><p>Success.</p></body></html>";
}
else{resp="<html><head></head><body><h1>Home<h1><p>Login Failed.</p></body></html>";}
writer.write(resp);
writer.flush();
}
});
response.setHeader("Content-Type", "text/html");
response.setEntity(entity);
}
boolean validatePassword(){
boolean pass=false;
//parse request body here and check for the password if true return true/else false
return pass;
}
}
After looking around for ages I found the solution. Adding the following in the handle method does the trick.Thanks to the original poster
.http://www.androiddevblog.net/android/a-bare-minimum-web-server-for-android-platform
if (request instanceof HttpEntityEnclosingRequest) {
HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity();
if (entity != null) {
Log.v("RequestBody", EntityUtils.toString(entity, "UTF-8"));
entity.consumeContent();
}
}
I apologize if this isn't quite what you're asking, so if it's not, let me know.
You could use a JSONObject to return whether or not that password was verified as correct.
For example, if the password is correct, you could store the HTTP result as:
{"status":200,"confirmed":"true"}
Or "false" otherwise.
When you get back from the HTTP Post Request, you can store this result as a String, then make a JSONObject out of it. For example:
// Send the URL to a postRequest function and return the result as a String
String output = makePostRequest(url);
// Parse the String as a JSONObject and receive whether or not the login was confirmed
JSONObject o = new JSONObject(output);
String confirmed = o.getString("confirmed");
if (confirmed.equals("true")) {
// Password confirmed - redirect user to success page
} else {
// Password incorrect - redirect user to failure page
}
Note: in case you need an idea of how to receive the response code from the post request, here's some sample code:
String output = {};
// Use bufferedreader and stringbuilder to build an output string (where conn is your HTTPUrlConnection object you used to make the post request
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
// Loop through response to build JSON String
while((line = br.readLine()) != null) {
sb.append(line + "\n");
}
// Set output from response
output = sb.toString();
And now output is the String you can turn into a JSONObject.
Does any of this help?
Edit:
Okay, so the String you will be getting will be in the format of {"password":"somepassword"}. To parse this, try this out:
String s = /* the string in the format {"password":"somepassword"} */
JSONObject o = new JSONObject(s);
String password = o.getString("password");
if (password.equals(random_password_at_beginning_of_webservice) {
// Password confirmed - redirect user to success page
} else {
// Password incorrect - redirect user to failure page
}
I have the following code which takes a normal HTTP GET Request and returns the output html as a string.
public static String getURLContent(String URL){
String Result = "";
String IP = "http://localhost/";
try {
// Create a URL for the desired page
URL url = new URL(IP.concat(URL));
// Read all the text returned by the server
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
String str;
while ((str = in.readLine()) != null) {
// str is one line of text; readLine() strips the newline character(s)
Result = Result+str+"~";
}
in.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return Result;
}
I would like to implement the same sort of thing for an unsigned ssl certificate but I am a bit of a novice at Java or Android programming and find some previous responses to similar questions very confusing.
Could someone change the code above to work with HTTPS requests?
One other question, would there be a risk of a middle-man-attack if I sent unencrypyted data via the GET request and print out database entries onto the webpage that the function returns the content of. Would it be better to use a POST request?
The reason I chose to use SSL is because someone told me that the data sent is encrypted. The data is sensitive and if I send something like localhost/login.php?user=jim&password=sd7vbsksd8 which would return "user=jim permission=admin age=23" which is data that I don't want others to see if they simply used a browser and sent the same request.
Try this:
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
public class TestHttpGet {
public void executeHttpGet() throws Exception {
BufferedReader in = null;
try {
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet();
request.setURI(new URI("http://w3mentor.com/"));
HttpResponse response = client.execute(request);
in = new BufferedReader
(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
}
in.close();
String page = sb.toString();
System.out.println(page);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
We can add parameters to an HTTP Get request as
HttpGet method = new HttpGet("http://w3mentor.com/download.aspx?key=valueGoesHere");
client.execute(method);
Android should automatically work with ssl. Maybe ssl certificate you are using on localhost is not trusted? Check this: Trusting all certificates using HttpClient over HTTPS
Check if you are able to browse https://yourhost/login.php?user=jim&password=sd7vbsksd8 using your browser.