I'm trying to send JSON using the code below in Android. I don't have access to server side code just database where data supposed to be stored. The guy who handles the server side says he sees my request as GET. I really don't understand why. I tried several examples I found on the internet and none of them worked.
public void uploadNewTask(View view) {
AsyncT asynct = new AsyncT();
asynct.execute();
}
class AsyncT extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
try {
URL url = new URL("http://[...]/events/");
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setDoOutput(true);
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
httpURLConnection.setRequestProperty("Accept", "application/json; charset=UTF-8");
httpURLConnection.connect();
JSONObject jsonObject = new JSONObject();
jsonObject.put("title", "tytul1");
jsonObject.put("description", "opis1");
jsonObject.put("execution_time", "2017-05-01 12:30:00");
/*
OutputStreamWriter writer = new OutputStreamWriter(httpURLConnection.getOutputStream());
String output = jsonObject.toString();
writer.write(output);
writer.flush();
writer.close();*/
DataOutputStream wr = new DataOutputStream(httpURLConnection.getOutputStream());
wr.writeBytes(jsonObject.toString());
wr.flush();
wr.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
}
Here's my suggestion to you: Use libraries to make your work easy. Libraries that do most of the work for you and makes request faster and better error handling.
So how do you make a POST call?
Step 1: Add these two libraries to your gradle dependencies:
compile 'com.google.code.gson:gson:2.8.0' // to work with Json
compile 'com.squareup.okhttp:okhttp:2.7.5' // to make http requests
Step 2: Create POST body JSON object and make a POST call.
Declare this in your Activity/Fragment:
final MediaType jsonMediaType = MediaType.parse("application/json");
Then, in your AsyncTask, do this:
try {
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("title", "tytul1");
jsonObject.addProperty("description", "opis1");
jsonObject.addProperty("execution_time", "2017-05-01 12:30:00");
RequestBody requestBody = RequestBody.create(jsonMediaType, new Gson().toJson(jsonObject));
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://[...]/events/")
.post(requestBody)
.addHeader("content-type", "application/json")
.build();
Response response = client.newCall(request).execute();
// this is the response of the post request
String res = response.body().string();
// you can get the response as json like this
JsonObject responseJson = new Gson().fromJson(res, JsonObject.class);
} catch (Exception e) {
Log.e(TAG, e.toString());
}
Note: If you want more example about this network library, see their official examples here
if you want to send get request, why there are not string like this format.http://xxx?requestParam=value&requestparam2=value2 format. I remember i used such way send get request to server side in my project do have string concatenation.
Related
im beginner of java developer, how can i get response from my JSON POST server in textview? try lot of tutorial/ guide from youtube and other website, still not working, some of classes are deprecated too. anyone here help?
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
etUsername = findViewById(R.id.et_username);
etPassword = findViewById(R.id.et_password);
btSubmit = findViewById(R.id.bt_submit);
TextView TextViewResult;
TextViewResult = findViewById(R.id.text_view_result);
this my JSON POST coding.
class AsyncT extends AsyncTask<Void,Void,Void>{
#Override
protected Void doInBackground(Void... params) {
try {
URL url = new URL("https://pltmuar.eschool.edu.my/es_api/app_login.php"); //Enter URL here
HttpURLConnection httpURLConnection = (HttpURLConnection)url.openConnection();
httpURLConnection.setDoOutput(true);
httpURLConnection.setRequestMethod("POST"); // here you are telling that it is a POST request, which can be changed into "PUT", "GET", "DELETE" etc.
httpURLConnection.setRequestProperty("Content-Type", "application/json"); // here you are setting the `Content-Type` for the data you are sending which is `application/json`
httpURLConnection.connect();
JSONObject jsonObject = new JSONObject();
jsonObject.put("app_id", "123456");
jsonObject.put("username", "testparent");
jsonObject.put("password", "123456");
jsonObject.put("firebase_token", "abc123");
DataOutputStream wr = new DataOutputStream(httpURLConnection.getOutputStream());
OutputStream out = httpURLConnection.getOutputStream();
wr.writeBytes(jsonObject.toString());
wr.flush();
wr.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
TextViewResult.setText();
}
}
thanks !
Use Volley library which is by google, for making network calls
implementation 'com.android.volley:volley:1.2.1'
add above as a dependency in your app level build.gradle file
Assuming you are making a POST request for which you are sending some params and you are receiving JSON response in return
Inside onResponse method of Volley Post, you will get your response. You will have to parse your JSON response first according to the API response format, and then finally you can set the data from response to your text view as below:
yourTextView.setText(jsonObject.getString("first_name").toString());
I have searched everywhere but I couldn't find my answer, is there a way to make a simple HTTP request? I want to request a PHP page / script on one of my websites but I don't want to show the webpage.
If possible I even want to do it in the background (in a BroadcastReceiver)
UPDATE
This is a very old answer. I definitely won't recommend Apache's client anymore. Instead use either:
Retrofit
OkHttp
Volley
HttpUrlConnection
Original Answer
First of all, request a permission to access network, add following to your manifest:
<uses-permission android:name="android.permission.INTERNET" />
Then the easiest way is to use Apache http client bundled with Android:
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = httpclient.execute(new HttpGet(URL));
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpStatus.SC_OK){
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
String responseString = out.toString();
out.close();
//..more logic
} else{
//Closes the connection.
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
If you want it to run on separate thread I'd recommend extending AsyncTask:
class RequestTask extends AsyncTask<String, String, String>{
#Override
protected String doInBackground(String... uri) {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
String responseString = null;
try {
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);
responseString = out.toString();
out.close();
} else{
//Closes the connection.
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (ClientProtocolException e) {
//TODO Handle problems..
} catch (IOException e) {
//TODO Handle problems..
}
return responseString;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
//Do anything with response..
}
}
You then can make a request by:
new RequestTask().execute("http://stackoverflow.com");
unless you have an explicit reason to choose the Apache HttpClient, you should prefer java.net.URLConnection. you can find plenty of examples of how to use it on the web.
we've also improved the Android documentation since your original post: http://developer.android.com/reference/java/net/HttpURLConnection.html
and we've talked about the trade-offs on the official blog: http://android-developers.blogspot.com/2011/09/androids-http-clients.html
Note: The Apache HTTP Client bundled with Android is now deprecated in favor of HttpURLConnection. Please see the Android Developers Blog for more details.
Add <uses-permission android:name="android.permission.INTERNET" /> to your manifest.
You would then retrieve a web page like so:
URL url = new URL("http://www.android.com/");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
readStream(in);
}
finally {
urlConnection.disconnect();
}
I also suggest running it on a separate thread:
class RequestTask extends AsyncTask<String, String, String>{
#Override
protected String doInBackground(String... uri) {
String responseString = null;
try {
URL url = new URL(myurl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
if(conn.getResponseCode() == HttpsURLConnection.HTTP_OK){
// Do normal input or output stream reading
}
else {
response = "FAILED"; // See documentation for more info on response handling
}
} catch (ClientProtocolException e) {
//TODO Handle problems..
} catch (IOException e) {
//TODO Handle problems..
}
return responseString;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
//Do anything with response..
}
}
See the documentation for more information on response handling and POST requests.
The most simple way is using the Android lib called Volley
Volley offers the following benefits:
Automatic scheduling of network requests. Multiple concurrent network
connections. Transparent disk and memory response caching with
standard HTTP cache coherence. Support for request prioritization.
Cancellation request API. You can cancel a single request, or you can
set blocks or scopes of requests to cancel. Ease of customization, for
example, for retry and backoff. Strong ordering that makes it easy to
correctly populate your UI with data fetched asynchronously from the
network. Debugging and tracing tools.
You can send a http/https request as simple as this:
// Instantiate the RequestQueue.
RequestQueue queue = Volley.newRequestQueue(this);
String url ="http://www.yourapi.com";
JsonObjectRequest request = new JsonObjectRequest(url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
if (null != response) {
try {
//handle your response
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
queue.add(request);
In this case, you needn't consider "running in the background" or "using cache" yourself as all of these has already been done by Volley.
Use Volley as suggested above. Add following into build.gradle (Module: app)
implementation 'com.android.volley:volley:1.1.1'
Add following into AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET" />
And add following to you Activity code:
public void httpCall(String url) {
RequestQueue queue = Volley.newRequestQueue(this);
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
// enjoy your response
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// enjoy your error status
}
});
queue.add(stringRequest);
}
It replaces http client and it is very simple.
private String getToServer(String service) throws IOException {
HttpGet httpget = new HttpGet(service);
ResponseHandler<String> responseHandler = new BasicResponseHandler();
return new DefaultHttpClient().execute(httpget, responseHandler);
}
Regards
With a thread:
private class LoadingThread extends Thread {
Handler handler;
LoadingThread(Handler h) {
handler = h;
}
#Override
public void run() {
Message m = handler.obtainMessage();
try {
BufferedReader in =
new BufferedReader(new InputStreamReader(url.openStream()));
String page = "";
String inLine;
while ((inLine = in.readLine()) != null) {
page += inLine;
}
in.close();
Bundle b = new Bundle();
b.putString("result", page);
m.setData(b);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
handler.sendMessage(m);
}
}
As none of the answers described a way to perform requests with OkHttp, which is very popular http client nowadays for Android and Java in general, I am going to provide a simple example:
//get an instance of the client
OkHttpClient client = new OkHttpClient();
//add parameters
HttpUrl.Builder urlBuilder = HttpUrl.parse("https://www.example.com").newBuilder();
urlBuilder.addQueryParameter("query", "stack-overflow");
String url = urlBuilder.build().toString();
//build the request
Request request = new Request.Builder().url(url).build();
//execute
Response response = client.newCall(request).execute();
The clear advantage of this library is that it abstracts us from some low level details, providing more friendly and secure ways to interact with them. The syntax is also simplified and permits to write nice code.
I made this for a webservice to requerst on URL, using a Gson lib:
Client:
public EstabelecimentoList getListaEstabelecimentoPorPromocao(){
EstabelecimentoList estabelecimentoList = new EstabelecimentoList();
try{
URL url = new URL("http://" + Conexao.getSERVIDOR()+ "/cardapio.online/rest/recursos/busca_estabelecimento_promocao_android");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
if (con.getResponseCode() != 200) {
throw new RuntimeException("HTTP error code : "+ con.getResponseCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader((con.getInputStream())));
estabelecimentoList = new Gson().fromJson(br, EstabelecimentoList.class);
con.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
return estabelecimentoList;
}
Look at this awesome new library which is available via gradle :)
build.gradle: compile 'com.apptakk.http_request:http-request:0.1.2'
Usage:
new HttpRequestTask(
new HttpRequest("http://httpbin.org/post", HttpRequest.POST, "{ \"some\": \"data\" }"),
new HttpRequest.Handler() {
#Override
public void response(HttpResponse response) {
if (response.code == 200) {
Log.d(this.getClass().toString(), "Request successful!");
} else {
Log.e(this.getClass().toString(), "Request unsuccessful: " + response);
}
}
}).execute();
https://github.com/erf/http-request
This is the new code for HTTP Get/POST request in android. HTTPClient is depricated and may not be available as it was in my case.
Firstly add the two dependencies in build.gradle:
compile 'org.apache.httpcomponents:httpcore:4.4.1'
compile 'org.apache.httpcomponents:httpclient:4.5'
Then write this code in ASyncTask in doBackground method.
URL url = new URL("http://localhost:8080/web/get?key=value");
HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
urlConnection.setRequestMethod("GET");
int statusCode = urlConnection.getResponseCode();
if (statusCode == 200) {
InputStream it = new BufferedInputStream(urlConnection.getInputStream());
InputStreamReader read = new InputStreamReader(it);
BufferedReader buff = new BufferedReader(read);
StringBuilder dta = new StringBuilder();
String chunks ;
while((chunks = buff.readLine()) != null)
{
dta.append(chunks);
}
}
else
{
//Handle else
}
For me, the easiest way is using library called Retrofit2
We just need to create an Interface that contain our request method, parameters, and also we can make custom header for each request :
public interface MyService {
#GET("users/{user}/repos")
Call<List<Repo>> listRepos(#Path("user") String user);
#GET("user")
Call<UserDetails> getUserDetails(#Header("Authorization") String credentials);
#POST("users/new")
Call<User> createUser(#Body User user);
#FormUrlEncoded
#POST("user/edit")
Call<User> updateUser(#Field("first_name") String first,
#Field("last_name") String last);
#Multipart
#PUT("user/photo")
Call<User> updateUser(#Part("photo") RequestBody photo,
#Part("description") RequestBody description);
#Headers({
"Accept: application/vnd.github.v3.full+json",
"User-Agent: Retrofit-Sample-App"
})
#GET("users/{username}")
Call<User> getUser(#Path("username") String username);
}
And the best is, we can do it asynchronously easily using enqueue method
I'm currently working on a project using an IoT platform " Thingsboard " where I've have created multiple devices, and I want to send data to each one of the devices from a JSON File, I'm using Rest Api to perform this request, but I've struggling for a while how to get the access token of my devices and parse each one of them in my request as a header param. I was just doing manually by getting them with Curl, but I want now to do it automatically. I know that Thingsboard has a Rest client Api written in java (https://thingsboard.io/docs/reference/rest-client/) so I've tried to use that in my script but I's not working. I'm new to working with Rest Api so if anybody can gie me a clue it would be so helpful.
here's a part of my code for the requests :
private static String token;
public String getToken() {
return token;
}
String paramValue = "param\\with\\backslash";
String yourURLStr = "http://host.com?param=" + java.net.URLEncoder.encode(paramValue, "UTF-8");
URL url2 = new URL("https://demo.thingsboard.io/api/v1/token/telemetry?token=$JWT_TOKEN");
HttpsURLConnection conn = (HttpsURLConnection) url2.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Accept", "application/json");
conn.setRequestProperty(JWT_TOKEN_HEADER_PARAM, "Bearer" +token);
conn.setDoOutput(true);
OutputStream outStream = conn.getOutputStream();
OutputStreamWriter outStreamWriter = new OutputStreamWriter(outStream, "UTF-8");
outStreamWriter.write(list.toString());
outStreamWriter.flush();
outStreamWriter.close();
outStream.close();
String response = null;
System.out.println(conn.getResponseCode());
System.out.println(conn.getResponseMessage());
DataInputStream input1 = null;
input1 = new DataInputStream (conn.getInputStream());
while (null != ((response = input1.readLine()))) {
System.out.println(response);
input1.close ();
}
}
catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
If you are trying to get the JWT-token to authenticate the following java should work:
Request request = Request.Post("http://THINGSBOARD_URL/api/auth/login");
String body = "{\"username\":\"tenant#thingsboard.org\", \"password\":\"tenant\"}";
request.bodyString(body,ContentType.APPLICATION_JSON);
request.setHeader("Content-Type", "application/json");
request.setHeader("Accept", "application/json");
HttpResponse httpResponse = request.execute().returnResponse();
System.out.println(httpResponse.getStatusLine());
if (httpResponse.getEntity() != null) {
String html = EntityUtils.toString(httpResponse.getEntity());
System.out.println(html);
}
Don't get confused with JWT-Token for tenant authentication and Access-Token for Device Authentication.
Hello stackoverflow users,
I am trying to write a post request (sends an SMS) that is called on a button click. The post request has:
One URL Parameter: api_key
One Header: "Content-Type" = "application/x-www-form-urlencoded"
Three JSON pairs: ("from", "insert#here"), ("to", "insert#here"), and ("body", "Hello, World")
By sending my POST request to a REST API endpoint URL, I want the SMS to send when the user clicks a button. This is what I have:
public class PostSMS extends AsyncTask<Void, String, String>
{
#Override
protected String doInBackground(Void... params) {
try {
MainActivity.text.setText("enteredTry");
URL url = new URL("https://api.apidaze.io/apikey/sms/send?api_secret=apisecret");
HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
MainActivity.text.setText("connectionBuilt");
urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
urlConnection.setRequestMethod("POST");
MainActivity.text.setText("connectionEstablished1");
urlConnection.connect();
MainActivity.text.setText("connectionEstablished23");
// Create JSONObject Request
JSONObject jsonRequest = new JSONObject();
jsonRequest.put("from", "1111111111");
jsonRequest.put("to", "1111111112");
jsonRequest.put("body", "Hello, World");
MainActivity.text.setText("jsonArrayConstructed");
// Write Request to output stream to server
OutputStreamWriter out = new OutputStreamWriter(urlConnection.getOutputStream());
out.write(jsonRequest.toString());
out.close();
MainActivity.text.setText("OutputStream written");
int statusCode = urlConnection.getResponseCode();
String statusMsg = urlConnection.getResponseMessage();
// Connection success. Proceed to fetch the response.
if (statusCode == 200)
{
InputStream it = new BufferedInputStream(urlConnection.getInputStream());
InputStreamReader read = new InputStreamReader(it);
BufferedReader buff = new BufferedReader(read);
StringBuilder dta = new StringBuilder();
String chunks;
while ((chunks = buff.readLine()) != null)
{
dta.append(chunks);
}
String returndata = dta.toString();
return returndata;
}
catch (ProtocolException e)
{
e.printStackTrace();
} catch (MalformedURLException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
} catch (Exception e)
{
e.printStackTrace();
}
return null;
}
}
Upon running this code in an OnClickListener, my TextView object (text in the code) only shows "connectionEstablished1" in the emulator, so it does not run the rest of the program.
After
urlConnection.setRequestMethod("POST");
MainActivity.text.setText("connectionEstablished1");
is run,
the program does not run anymore. There are no compile-time errors.
I have the
<uses-permission android:name="android.permission.INTERNET" />
permission as well.
Thanks!
I checked your code, it's working if you remove MainActivity.text.setText().
As Mike M. pointed out you shouldn't use MainActivity.text.setText() to track progress, you should use Logging for that. If you want to display progress to user you should use onProgressUpdate(String... values) and onPostExecute(String s) that can be overridden in AsyncTask.
Also you could try to debug your app once you get more familiar with Android studio interface, it's easier than checking Logs and StackTraces from catch blocks.
I use a simple WebServer from http://www.java2s.com/Code/Java/Network-Protocol/AverysimpleWebserverWhenitreceivesaHTTPrequestitsendstherequestbackasthereply.htm
and Android code from Sending json object via http post method in android
In my main Activity:
AsyncT asyncT = new AsyncT();
asyncT.execute();
Class:
class AsyncT extends AsyncTask<Void,Void,Void>{
#Override
protected Void doInBackground(Void... params) {
try {
URL url = new URL(""); //Enter URL here
HttpURLConnection httpURLConnection = (HttpURLConnection)url.openConnection();
httpURLConnection.setDoOutput(true);
httpURLConnection.setRequestMethod("POST"); // here you are telling that it is a POST request, which can be changed into "PUT", "GET", "DELETE" etc.
httpURLConnection.setRequestProperty("Content-Type", "application/json"); // here you are setting the `Content-Type` for the data you are sending which is `application/json`
httpURLConnection.connect();
JSONObject jsonObject = new JSONObject();
jsonObject.put("para_1", "arg_1");
DataOutputStream wr = new DataOutputStream(httpURLConnection.getOutputStream());
wr.writeBytes(jsonObject.toString());
wr.flush();
wr.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
}
The connection is established without any errors ("HostConnection::get() New Host Connection established"). However, I am not able to get in my Java server any information from the request. When I read from input stream
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
System.out.println(in);
I get java.io.BufferedReader#4d7hge12
And this outputs nothing:
String line;
while ((line = in.readLine()) != null) {
if (line.length() == 0)
break;
System.out.println(line);
}
Don't re-invent the wheel and use a library for this.
For example okhttp:
public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
OkHttpClient client = new OkHttpClient();
String post(String url, String json) throws IOException {
RequestBody body = RequestBody.create(JSON, json);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
Response response = client.newCall(request).execute();
return response.body().string();
}
If you want to call a REST-API you can use retrofit (which is build ontop of okhttp)
Assuming you're doing this as a learning exercise, so using another library isn't what you're looking for, I would suggest a couple of things:
(1) install Wireshark and see what the actual response coming back the server is, does it look sensible?
(2) break that line of code out into separate lines, is the InputStream / InputStreamReader null?