Android POST request with JSON - java

After researches i still cant send a JSON POST request to a server.
I already tried some older answers:
Java - sending HTTP parameters via POST method easily
[Android]-POST Json with HttpUrlConnection
Post request for registering user data on server by HttpUrlConnection
Sending json object via http post method in android
How to send a JSON object over Request with Android?
My current code is:
FloatingActionButton btn_sendMsg = (FloatingActionButton) findViewById(R.id.btn_sendMsg);
btn_sendMsg.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
/*Snackbar.make(view, "Sendevorgang...", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();*/
createMsg();
}
});
private void createMsg() {
Message message = new Message(txtbox_msg.getText().toString(), "testUser");
AsyncT asyncT = new AsyncT();
asyncT.execute(message);
}
AsyncT.java :
#Override
protected Message doInBackground(Message... params) {
try {
URL url = new URL("http://[ip]:[port]"); //in the real code, there is an ip and a port
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Accept","application/json");
conn.setDoOutput(true);
conn.setDoInput(true);
conn.connect();
JSONObject jsonParam = new JSONObject();
jsonParam.put("uname", params[0].getUser());
jsonParam.put("message", params[0].getMessage());
jsonParam.put("latitude", "0");
jsonParam.put("longitude", "0");
jsonParam.put("id", "1");
DataOutputStream os = new DataOutputStream(conn.getOutputStream());
os.writeBytes(URLEncoder.encode(jsonParam.toString(), "UTF-8"));
os.flush();
os.close();
Log.i("STATUS", String.valueOf(conn.getResponseCode()));
Log.i("MSG" , conn.getResponseMessage());
conn.disconnect();
} catch (Exception e) {
}
return null;
}
I'm getting the error code networkonmainthreadexception 500
How can i solve this?

Solved:
changed
os.writeBytes(URLEncoder.encode(jsonParam.toString(), "UTF-8"));
to
os.writeBytes(jsonParam.toString());
And put the code in a thread (thanks to #Ravi Sanker)
Working code:
public void sendPost() {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
URL url = new URL(urlAdress);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
conn.setRequestProperty("Accept","application/json");
conn.setDoOutput(true);
conn.setDoInput(true);
JSONObject jsonParam = new JSONObject();
jsonParam.put("timestamp", 1488873360);
jsonParam.put("uname", message.getUser());
jsonParam.put("message", message.getMessage());
jsonParam.put("latitude", 0D);
jsonParam.put("longitude", 0D);
Log.i("JSON", jsonParam.toString());
DataOutputStream os = new DataOutputStream(conn.getOutputStream());
//os.writeBytes(URLEncoder.encode(jsonParam.toString(), "UTF-8"));
os.writeBytes(jsonParam.toString());
os.flush();
os.close();
Log.i("STATUS", String.valueOf(conn.getResponseCode()));
Log.i("MSG" , conn.getResponseMessage());
conn.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread.start();
}

Can you try with writing this in the createMsg() method:
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
// The code written in doInBackground()
} catch (Exception e) {
e.printStackTrace();
}
}});
thread.start();
The networkonmainthread exception comes when you run the network operations on the same thread. But, since you're using an async task, it should work fine. But, just to confirm.

Related

Making HTTP Get call upon button press in android

I am totally new to android and trying to develop a basic application. I have used the default Navigation Drawer Activity from android while creating the project.
Basically, I am getting an exception when I am making an HTTP get req upon a button click. I have created a button that is all working fine. The button is created inside the HomeFragment.java.
Here is the code -
final Button button = root.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// new ApiCall("637", "22-05-2021", textView).start();
try {
// String finalUrl = address+"district_id="+this.district_id+"&date="+this.date;
URL url = new URL("https://cdn-api.co-vin.in/api/v2/appointment/sessions/public/findByDistrict/?district_id=637&date=22-05-2021");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("User-Agent", "PostmanRuntime/7.26.10");
con.setRequestProperty("Accept-Language", "en_US");
con.setRequestProperty("Content-Type", "application/json");
con.setRequestProperty("Accept", "application/json");
//Exception
BufferedReader in = new BufferedReader(new InputStreamReader( con.getInputStream())); // here exception coming////////////////////
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println(inputLine);
}
in.close();
} catch(MalformedURLException e) {
System.out.println("Malformed URL: " + e.getMessage());
textView.setText("Malformed");
} catch(IOException e) {
System.out.println("IOException: " + e.getMessage());
textView.setText("Exception");
}
catch (Exception e){
textView.setText("Exception");
e.printStackTrace();
}
}
});
This code of calling HTTP get req is all working fine when I do it purely in java in IntelliJ Idea.
I don't know why am I getting exceptions here.
Let me know
Thanks,
Akhi
As #Bhardwaj suggested, you can't make network calls in the main thread in Android. Create a background thread like this:
class RetrieveRemoteData extends AsyncTask<String, Void, YourResponseModelClass> {
private Exception exception;
protected YourResponseModelClass doInBackground(String... urls) {
// new ApiCall("637", "22-05-2021", textView).start();
try {
// String finalUrl = address+"district_id="+this.district_id+"&date="+this.date;
URL url = new URL("https://cdn-api.co-vin.in/api/v2/appointment/sessions/public/findByDistrict/?district_id=637&date=22-05-2021");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("User-Agent", "PostmanRuntime/7.26.10");
con.setRequestProperty("Accept-Language", "en_US");
con.setRequestProperty("Content-Type", "application/json");
con.setRequestProperty("Accept", "application/json");
//Exception
BufferedReader in = new BufferedReader(new InputStreamReader( con.getInputStream())); // here exception coming////////////////////
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println(inputLine);
}
in.close();
} catch(MalformedURLException e) {
System.out.println("Malformed URL: " + e.getMessage());
textView.setText("Malformed");
} catch(IOException e) {
System.out.println("IOException: " + e.getMessage());
textView.setText("Exception");
}
catch (Exception e){
textView.setText("Exception");
e.printStackTrace();
}
}
}
protected void onPostExecute(YourResponseModelClass responseObject) {
// write your code here what happens after getting response or exception
}
}
You can refer to this, this has a lot of detailed steps for your use case.
Additionally, try to include more details to your question like what exceptions are you getting to be more descriptive about your issues so that the contributors understand your question better and suggest you accurate solutions.

Java how to send special character is post

Im trying to send a post to a backend API from android and this is what I have but some special characters relating to application/x-www-form-urlencoded content type wont be sent or cause problems. Im wondering if there is a way to send the special characters in this format? (+,&) I'm attempting to send the message "This is a message + a test" but my database is getting "This is a message a test"
I've tried passing JSON but the backend that my co-students wrote doesn't accept JSON and returns a 401 not authorized error.
public void sendMessage() {
if(!mEdit.getText().toString().trim().matches("")) { //Cant send empty strings
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
URL url = new URL(Sendurl); //Create URL
HttpURLConnection conn = (HttpURLConnection) url.openConnection(); //Create a Connector
conn.setRequestMethod("POST"); //Dictate the Method
conn.setRequestProperty("Content-Type", "application/json; utf-8"); //Some other properties
conn.setRequestProperty("Accept", "application/json");
conn.setDoOutput(true);
conn.setDoInput(true);
//This part causes a 401 error because it is the equivalent of passing parameters but our backend uses body formatting
JSONObject jsonParam = new JSONObject();
Date date = new Date();
RequestParams params = new RequestParams();
params.put("username", "admin");
params.put("sessionID", 1);
params.put("cardNum", 111111111);
params.put("sentByStaff", "false");
params.put("message", "This is the message + a test");
params.put("time", date.getTime()/1000);
Log.i("JSON", params.toString());
// OutputStreamWriter os = new OutputStreamWriter(conn.getOutputStream()); //Prepare the connection for output
POST_PARAMS = params.toString(); //Converts post parameters to body type
System.out.println(POST_PARAMS);
try(OutputStream os = conn.getOutputStream()) {
byte[] input = POST_PARAMS.getBytes("utf-8");
os.write(input, 0, input.length);
os.flush();
os.close();
}
//os.write(POST_PARAMS); //Write our parameters to the post
//os.flush(); //Do the thing
//os.close();
Log.i("STATUS", String.valueOf(conn.getResponseCode())); //Debug
Log.i("MSG", conn.getResponseMessage()); //Debug
int responseCode = 0; //get response code
responseCode = conn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) { //On success
mEdit.setText("");
}
conn.disconnect(); //disconnect after attempting post
getMessage(); //update our messages
} catch (Exception e) { //dirty catch all
e.printStackTrace();
}
}
});
thread.start();
}
}

How to send a proper post request to WHMCS installation from android app?

I am trying to send an AddClient post request to my WHMCS installation through my android app but it keeps returning "result=error;message=You did not enter your first name".
I get it to authenticate successfully but it doesnt seem to be posting the jsonObject I am sending it.
Here is a link to WHMCS api documentation: https://developers.whmcs.com/api-reference/addclient/
public void createWHMCSUser(final String emailID, final String random, final String uid) {
final String AccessUserKey = "abc123";
final String AccessKey = "abc123";
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
URL url = new URL("http://whmcs.installation.com/includes/api.php?action=AddClient&username=abc123&password=abc123&accesskey=abc123");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Accept","application/json");
conn.setDoOutput(true);
conn.setDoInput(true);
JSONObject jsonParam = new JSONObject();
jsonParam.put("action", "AddClient");
jsonParam.put("identifier", AccessUserKey);
jsonParam.put("secret", AccessKey);
jsonParam.put("firstname", "User");
jsonParam.put("lastname", "Name");
jsonParam.put("email", emailID);
jsonParam.put("address1", "na");
jsonParam.put("city", "na");
jsonParam.put("state", "na");
jsonParam.put("postcode", "00000");
jsonParam.put("country", "US");
jsonParam.put("phonenumber", "0000000000");
jsonParam.put("password2", random);
jsonParam.put("repsonsetype", "json");
Log.i("JSON", jsonParam.toString());
DataOutputStream os = new DataOutputStream(conn.getOutputStream());
os.writeBytes(URLEncoder.encode(jsonParam.toString(), "UTF-8"));
//os.writeBytes(jsonParam.toString());
os.flush();
os.close();
Log.i("STATUS", String.valueOf(conn.getResponseCode()));
Log.i("MSG", conn.getResponseMessage());
conn.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread.start();
}
It should return "result=success".
But actually returns "result=error;message=You did not enter your first name".
It’s seems your API doesn’t work in this sample.
try Postman and if json doesn’t work there, issue is in your api.

HttpUrlConnection returns -1 status code

I have problem with connecting to my server. Following code returns -1 as response code and null as response message.
protected Boolean doInBackground(MyTaskParams... params) {
URL url = null;
String load = params[0].jobj.toString();
try {
url = new URL(params[0].serverUrl);
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setConnectTimeout(3000);
urlConnection.setReadTimeout(3000);
urlConnection.setRequestMethod("POST");
urlConnection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
urlConnection.setChunkedStreamingMode(0);
urlConnection.setDoOutput(true);
urlConnection.setDoInput(true);
urlConnection.connect();
OutputStreamWriter osw = new OutputStreamWriter(urlConnection.getOutputStream());
osw.write(load);
osw.flush();
osw.close();
if(urlConnection.getResponseCode()==200 && urlConnection.getResponseMessage().contains("true") ) return true;
else return false;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
While debbuging url and body content (which is load in code) are correct. When I try to connect with the server using those params with Fiddler it works perfectly and I get 200 status code. Do you have any ideas what is wrong?
Im passing jData object as the jobj:
JSONObject User=new JSONObject();
JSONObject Mobile=new JSONObject();
JSONObject jData=new JSONObject();
try {
User.put ("UserLogin", "test");
User.put ("UserPassword", "test");
Mobile.put ("MobileIDD", IDD);
Mobile.put("MobileToken", token);
jData.put("Mobile", Mobile);
jData.put("User", User);
} catch (JSONException e) {
e.printStackTrace();
}
#EDIT
Solution with System.setProperty("http.keepAlive", "false") didnt help.
I solved the problem. It was in this line:
if(urlConnection.getResponseCode()==200 && urlConnection.getResponseMessage().contains("true") ) return true;
When I changed it to:
int code = urlConnection.getResponseCode();
if (code==200.....)
It started working.

I can't persist Login statement in Android

I set Cookiemanager with CookiePolicy.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_intro);
CookieManager cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
CookieHandler.setDefault(cookieManager);
setViews();
}
public void onClick(View v) {
GetTimetable getTimetable = new GetTimetable();
getTimetable.execute();
}
public class GetTimetable extends AsyncTask<Void, Void, Void> {
#Override
protected String doInBackground(Void... params) {
Timetable timetable = new Timetable();
timetable.start();
return null;
}
}
And I send requests.
public void start() {
try {
URL url = new URL(LOGIN_URL);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
urlConnection.setRequestMethod("POST");
urlConnection.setDoOutput(true);
urlConnection.setChunkedStreamingMode(0);
String urlParameters = URL_PARAMETERS;
DataOutputStream out = new DataOutputStream(urlConnection.getOutputStream());
out.writeBytes(urlParameters);
out.flush();
out.close();
} finally {
urlConnection.disconnect();
}
} catch (Exception e) {
e.printStackTrace();
}
try {
URL url = new URL(TARGET_URL);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
urlConnection.setRequestMethod("GET");
BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuffer response = new StringBuffer();
while (in.readLine() != null) {
response.append(in.readLine());
}
in.close();
System.out.println(response.toString());
} finally {
urlConnection.disconnect();
}
} catch (Exception e) {
e.printStackTrace();
}
}
I tested start() method in Eclipse with only Java and it worked.
Login by POST request, and get contents by GET request. but, in Android, it seems that it doesn't persist Login statement because POST request return headers successfully but Get request doesn't work at all.
I got stucked.
I really want to know how can I persist Login statement.
Thanks..!!

Categories

Resources