here is for several days I block on a proleme. I have to send a post request with json data to a server and I try this:
private void sendRequestInfo() {
JSONObject json = new JSONObject();
try {
json.put("email", "test#gmail.com");
json.put("password", "abcd");
} catch (JSONException e) {
e.printStackTrace();
}
mRequestQueue = Volley.newRequestQueue(this);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, url, json,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
resultOne.setText(response.toString());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
resultOne.setText(error.toString());
}
});
mRequestQueue.add(jsonObjectRequest);
}
communication with the server seems to be done since node brings out this line:
Executing (default): SELECT id, username, password, services, createdAt, updatedAt FROM users AS users WHERE users.username = 'register#gmail.com' LIMIT 1;
but I have this error:
"Value Logged of type java.lang.String cannot be converted to JSONObject"
normally the node server should send me back "user not found" I do not understand this error if someone can help me.
Related
How to make a PUT request using HttpURLConnection with query parameters?
I am trying to consume a third party REST API using HttpURLConnection but when I try to pass the parameters in the URL, it doesn't work and throw an error as shown below:
The REST API Url could not be found in the mappings registry
This is the code block that doesn't work for me as of now:
URL url;
StringBuffer response = new StringBuffer();
try
{
url = new URL(" http://thirdparty.com/party/api/v2/ksp/12/ks");
HttpURLConnection httpURL = (HttpURLConnection) url.openConnection();
httpURL.setDoOutput(true);
httpURL.setRequestMethod("PUT");
StringBuilder sbUrl = new StringBuilder("parameter1_id=");
sbUrl.append(getParameter1Value())
.append("¶meter2_id=")
.append(getParameter2Value());
final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(httpURL.getOutputStream()));
writer.write(sbUrl.toString());
writer.flush();
writer.close();
// throw the exception here in case invocation of web service
if (httpURL.getResponseCode() != 200)
{
// throw exception
}
else
{
//SUCCESS
}
}
catch (IOException e)
{
}
When I provide these parameters in the Body as form-data parameters, the REST API seems provide the response.
My question here is that how do I make this work with HttpURLConnection?
What have I tried till now?
I have tried to modify the above to something like below, but it doesn't work.
try
{
url = new URL(" http://thirdparty.com/party/api/v2/ksp/12/ks");
HttpURLConnection httpURL = (HttpURLConnection) url.openConnection();
httpURL.setDoOutput(true);
httpURL.setRequestMethod("PUT");
httpURL.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + "----WebKitFormBoundarydklhfklsdfhlksh");
dataOutputStream = new DataOutputStream(urlConnection.getOutputStream());
dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"parameter1_id\"");
dataOutputStream.writeBytes("\r\n" + "parameter1Value" +"\r\n");
dataOutputStream.writeBytes("--" + "----WebKitFormBoundarydklhfklsdfhlksh");
dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"parameter2_id\"");
dataOutputStream.writeBytes("\r\n" + "parameter2Value" + "\r\n");
dataOutputStream.writeBytes("--" + "----WebKitFormBoundarydklhfklsdfhlksh" + "--");
dataOutputStream.flush();
dataOutputStream.close();
urlConnection.connect();
// throw the exception here in case invocation of web service
if (httpURL.getResponseCode() != 200)
{
// throw exception
}
else
{
//SUCCESS
}
}
catch (IOException e)
{
}
EDIT: It throws an error with response code as 500
EDIT: Just to clarify, I'm not trying to upload a file but trying to send the parameters inside the BODY (like Query parameters instead of being sent as URL parameters).
Any pointers or suggestions on this are very much appreciated.
You talk about 'query parameters' and 'parameters in the URL', but neither of the approaches you show does any such things. Both your approaches (try to) send parameters in the request body, aka 'entity', not in the URL. Although body contents may be involved in an application-level query, they are NOT query string aka query parameters at the HTTP level. You also ask 'how do I make this work with HttpURLConnection' as if that were a change or difference when both your attempts already use it.
Your first attempt looks almost correct. It should work if
you .setRequestProperty("Content-type", "application/x-www-form-urlencoded") (which is not automatic) and your values either are URLencoded or don't need it (no reserved characters) (depending on the server it may be enough to have no ampersand or equalsign)
Your second attempt also is fairly close. You need to write a boundary before the first part as well, and for each part after Content-disposition: form-data; name="blah" you need one CRLF to end that header line and a second CRLF to end the header block. (MIME multipart format allows multiple header lines in general, although in this case only one is needed.) And the end boundary should be followed by a CRLF (after the extra --).
Both only if you have the URL correct, of course. Nothing will work without the correct URL.
Best Method to Call WebService with HttpUrlConnection PUT Method
ApiListener apilistener=null;
public void updateWorker()
{
progressDialog = ProgressDialog.show(myContext, "Message",
progressDialog.setCancelable(false);
progressDialog.setCanceledOnTouchOutside(false);
Thread runThread = new Thread(new Runnable() {
#Override
public void run() {
HttpAppRequest http = new HttpAppRequest();
try {
JSONObject paramObject = new JSONObject();
JSONObject dataObject = new JSONObject();
dataObject.put("id", csId);
}
paramObject.put("data", dataObject);
Log.e(AppConstants.TAG, "Param = " + paramObject.toString());
AppResponse response = http.putJSONData(BASE_URL + "/updateapi", paramObject.toString(), true);
if (response.getStatusCode() == 200) {
String csUpdateResult = response.getContentData();
Log.e(AppConstants.TAG, csUpdateResult);
JSONObject updateObject = new JSONObject(csUpdateResult);
Message completeMessage = handler.obtainMessage(1, updateObject);
completeMessage.sendToTarget();
} else {
handler.sendEmptyMessage(-1);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
String csMessage = myContext.getResources().getString(R.string.id_network_response_failure);
Message completeMessage = handler.obtainMessage(0, csMessage);
completeMessage.sendToTarget();
}
}
});
runThread.start();
}
/*******************************************************************************************************/ Handler Api Response Here
Handler handler= new Handler() {
#Override
public void handleMessage(Message inputMessage) {
progressDialog.dismiss();
if (inputMessage.what == 1) {
try {
JSONObject msgObject = (JSONObject) inputMessage.obj;
if (msgObject.has("result")) {
JSONObject resultObject = msgObject.getJSONObject("result");
if (resultObject.has("status")) {
String csStatus = resultObject.getString("status");
if (csStatus.equalsIgnoreCase("success")) {
apilistener.onUpdate(resultObject.getString("msg"));
}
} else {
if(resultObject.has("status"))
{
apilistener.onFailed(resultObject.getString("reason"));
}
}
}
} catch (JSONException e) {
CommonMethods.showMessageBox("", e.getMessage(), myContext);
}
} else if (inputMessage.what == 0) {
String csMessage = (String) inputMessage.obj;
CommonMethods.showMessageBox("", csMessage, myContext);
}
}
};
//CallBack Listener to parent Activity/Fragment
//User listener like this
public interface ApiListener extends EventListener
{
void onSuccess(String msg);
void onFaiulure(String msg);
}
public void setListener(ApiListener listener)
{
apilistener=listener;
}
}
I'm using Volley StringRequest to post a query to my server and I seeing that in about 20% of cases, the request is successful but onErrorResponse is called instead of onResponse.
Here is my request code:
StringRequest stringRequest = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d("App", "[MainActivity] post successful");
// run very important routine only when post is successful
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("App", "[MainActivity] failed to post");
if (error == null) {
Log.e("App", "no error");
}
else if (error.networkResponse != null) {
Log.e("App", String.valueOf(error.networkResponse.statusCode));
if(error.networkResponse.data != null) {
try {
Log.e("App", new String(error.networkResponse.data, "UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
else {
Log.e("App", "no network response");
}
}
});
requestQueue.add(stringRequest);
20% of the time I see:
E/App: [MainActivity] failed to post
E/App: no network response
but in my server logs I see a 200 message and the data created by the post is in my database.
Why would Volley throw an error on a successful post?
UPDATE
Log.e("App", "error message: " + error.getMessage());
prints: E/App: error message: null
What is the error message returned by volley? Check it by volleyError.getMessage().
I am attempting to use the Okhttp library to connect my android app to my server via API.
My API call is happening on a button click and I am receiving the following android.os.NetworkOnMainThreadException. I understand that this is due the fact I am attempting network calls on the main thread but I am also struggling to find a clean solution on Android as to how make this code use another thread (async calls).
#Override
public void onClick(View v) {
switch (v.getId()){
//if login button is clicked
case R.id.btLogin:
try {
String getResponse = doGetRequest("http://myurl/api/");
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
String doGetRequest(String url) throws IOException{
Request request = new Request.Builder()
.url(url)
.build();
Response response = client.newCall(request).execute();
return response.body().string();
}
Above is my code, and the exception is being thrown on the line
Response response = client.newCall(request).execute();
I've also read that Okhhtp supports Async requests but I really can't find a clean solution for Android as most seem to use a new class that uses AsyncTask<>?
To send an asynchronous request, use this:
void doGetRequest(String url) throws IOException{
Request request = new Request.Builder()
.url(url)
.build();
client.newCall(request)
.enqueue(new Callback() {
#Override
public void onFailure(final Call call, IOException e) {
// Error
runOnUiThread(new Runnable() {
#Override
public void run() {
// For the example, you can show an error dialog or a toast
// on the main UI thread
}
});
}
#Override
public void onResponse(Call call, final Response response) throws IOException {
String res = response.body().string();
// Do something with the response
}
});
}
& call it this way:
case R.id.btLogin:
try {
doGetRequest("http://myurl/api/");
} catch (IOException e) {
e.printStackTrace();
}
break;
It is somthing very weird.
I am using my android device to send messages to my node js server in LAN.
And now here comes the problem: When I send POST HTTP it DOES work. But when I send GET HTTP it DOES NOT work and the server even not recieve the get request.
This is my code for recieving the get:
app.get('/auth/facebook', passport.authenticate('facebook'));
And this is the code in androif for sending the GET:
public class Background_confirmation extends AsyncTask<Void, Integer, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// progressDialog = ProgressDialog.show(Confirmation.this, "Please wait...", "Retrieving data ...", true);
}
#Override
protected String doInBackground(Void... params) {
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet("http://localhost:8080/auth/facebook");
// replace with your url
HttpResponse response = null;
try {
response = client.execute(request);
Log.d("Response of GET request", response.toString());
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return response.toString();
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
// progressDialog.setCancelable(true);
// }
}
Someone have an idea for why it happen?
You are trying to get the data from localhost (i.e., your Android device) instead of from your server.
I have Android Studio with wamp server. I am trying to use a php file to access MySql database on phpmyadmin. I have tried the emulator and Android Device. I am always getting this error :
org.apache.http.conn.HttpHostConnectException: Connection to http://10.0.2.2:8080 refused
This is my MainActivity.jav file
public class MainActivity extends ActionBarActivity {
private TextView responseTView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.responseTView = (TextView) findViewById(R.id.response);
new getDetails().execute(new SqlConnector());
}
private void setTextToTextView(JSONArray jsonArray) {
String s = "";
for(int i=0; i<jsonArray.length();i++) {
JSONObject obj = null;
try {
obj = jsonArray.getJSONObject(i);
s = s + "ID: " + obj.getString("id") + "Customer Name:" + obj.getString("Customer");
}
catch(JSONException e) {
e.printStackTrace();
}
}
this.responseTView.setText(s);
}
private class getDetails extends AsyncTask<SqlConnector,Long,JSONArray> {
#Override
protected JSONArray doInBackground(SqlConnector... params) {
return params[0].getDetailsinJson();
}
#Override
protected void onPostExecute(JSONArray jsonArray) {
setTextToTextView(jsonArray);
}
}
}
And this is my SqlConnector.java file
public class SqlConnector {
public JSONArray getDetailsinJson() {
String url = "http://10.0.2.2:8080/D:/Database/main1.php";
HttpEntity httpEntity = null;
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
Log.d("This is inside HTTP try block.","No error..");
HttpResponse httpResponse = httpClient.execute(httpGet); //Using Logs, it's this line that brings on the error. That's my understanding.
httpEntity=httpResponse.getEntity();
}
catch(ClientProtocolException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
Log.d("Inside SqlConnector Class", "ajsdhlk");
JSONArray jsonArray = null;
if(httpEntity != null) {
try {
String response= EntityUtils.toString(httpEntity);
Log.e("This is the response", response);
jsonArray = new JSONArray(response);
}
catch(JSONException e) {
Log.d("This is inside Catch block.","Error in JSONArray");
e.printStackTrace();
}
catch(IOException e) {
Log.d("This is inside catch block.","IOException");
e.printStackTrace();
}
}
return jsonArray;
}
}
I have read many posts on Stackoverflow over similar problems. But, I am not able to get past this error after trying many things. I tried changing the IP I have used but it doesn't help. Please help.
I am quite new to Android Studio, so please explain the solutions. Thanks a lot for help.
After trying lot of options for hours. I changed my server. I used an online web hosting site to store my files. And, this somehow stopped this error. If you think there is some other way out, to use wamp then please do let me know.
I managed to fix this problem by writing my IP address from cmd -> ipconfig in the url:
String url = "http://192.168.x.x/D:/Database/main1.php";