I'm currently trying to send a simple POST-request via Google Volley to my server.
Therefore I've written the following lines of code:
Map<String, String> params = new HashMap<String, String>();
params.put("regId", "skdjasjdaljdlksajskl");
JSONObject object = new JSONObject(params);
JsonObjectRequest request = new JsonObjectRequest(Method.POST,
"address_of_my_server/method", object,
successListener, errorListener);
queue.add(request);
But I get an Error 500 returned, which says, that there is a missing parameter (regId). I've tried the same with a GET-Request, but I got the same result.
Only when I'm using a StringRequest with a formatted URL like "address_of_my_server/method?regId=sadlasjdlasdklsj" the server replies with 200.
I get the exact same result when I use a StringRequest like:
StringRequest request = new StringRequest(Method.POST,
"myurl", successListener,
errorListener){
#Override
protected Map<String, String> getParams()
throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("regId", "skdjasjdaljdlksajskl");
return params;
}
};
Why is Volley ignoring my parameters?
I had same issue last week, but it is fixed now.
Your server accepts the Content-Type as form-data, when sending volley's JsonObjectRequest the request's content-type will be application/json so whole params will be sent as one json body, not as key value pairs as in Stringrequest.
Change the server code to get request params from http request body instead of getting it from keys(like $_REQUEST['name'] in php).
Use this helper class:
import java.io.UnsupportedEncodingException;
import java.util.Map;
import org.json.JSONException;
import org.json.JSONObject;
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.toolbox.HttpHeaderParser;
public class CustomRequest extends Request<JSONObject> {
private Listener<JSONObject> listener;
private Map<String, String> params;
public CustomRequest(String url, Map<String, String> params,
Listener<JSONObject> reponseListener, ErrorListener errorListener) {
super(Method.GET, url, errorListener);
this.listener = reponseListener;
this.params = params;
}
public CustomRequest(int method, String url, Map<String, String> params,
Listener<JSONObject> reponseListener, ErrorListener errorListener) {
super(method, url, errorListener);
this.listener = reponseListener;
this.params = params;
}
protected Map<String, String> getParams()
throws com.android.volley.AuthFailureError {
return params;
};
#Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString = new String(response.data,
HttpHeaderParser.parseCharset(response.headers));
return Response.success(new JSONObject(jsonString),
HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JSONException je) {
return Response.error(new ParseError(je));
}
}
#Override
protected void deliverResponse(JSONObject response) {
// TODO Auto-generated method stub
listener.onResponse(response);
}
}
Woking example with the issue that Rajesh Batth mentioned
Java code:
JSONObject obj = new JSONObject();
try {
obj.put("id", "1");
obj.put("name", "myname");
} catch (JSONException e) {
e.printStackTrace();
}
JsonObjectRequest jsObjRequest = new JsonObjectRequest(
Request.Method.POST, url, obj, listener, errorlistener);
RequestQueue queue = Volley.newRequestQueue(context);
queue.add(jsObjRequest);
PHP-Code:
$body = file_get_contents('php://input');
$postvars = json_decode($body, true);
$id = $postvars["id"];
$name = $postvars["name"];
Note:
The PHP-Vars $_POST and $_REQUEST and $_GET are empty if you are not sending additional GET-VARS.
EDIT:
I deleted my previous answer since it wasn't accurate.
I'll go over what I know today:
Apparently, getParams should work. But it doesn't always.
I have debugged it myself, and it seems that it is being called when performing a PUT or POST request, and the params provided in that method are in a regular GET parameters string (?param1=value1¶m2=value2...) and encoded and put in the body.
I don't know why but for some reason this doesn't work for some servers.
The best alternate way I know to send parameters, is to put your parameters in a JSONObject and encode its contents in the request's body, using the request constructor.
Thi's my solution
Solution 1
public void getData() {
final RequestQueue queue = Volley.newRequestQueue(this);
StringRequest postRequest = new StringRequest(Request.Method.POST, "192.168.0.0/XYZ",new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONArray myArray = new JSONArray(response);
for(int i = 0; i < myArray.length(); i++)
{
JSONObject jObj = myArray.getJSONObject(i);
String category = jObj.getString("nameUser");
Log.e("value", category);
}
} catch (JSONException e) {
e.printStackTrace();
Log.e("error: ", e.getMessage());
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//Toast.makeText(context,"Error : ").show();
}
}){
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("id_user", "1");
return params;
}
};
queue.add(postRequest);
}
Solution 2
remember that if you use php,the $_POST[''];
not working, her more information.
Good Luck
Related
I am not sure if this is the right approach to the following problem:
I have to record some GPS Data and store it in a JSON Array. This data is to be sent to the server to be stored in a database. The server is capable of handling a JSON Array of any length. The relevant code is:
public void onLocationChanged(final Location location) {
try{
JSONObject temp = new JSONObject();
temp.put("trackerid", prefs.getString("trackerid", "Some ID"));
temp.put("latitude", location.getLatitude());
temp.put("longitude", location.getLongitude());
Calendar time = Calendar.getInstance();
Date currentLocalTime = time.getTime();
SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-d hh:m:ss", Locale.ENGLISH);
temp.put("timestamp",sdf.format(currentLocalTime));
arrJ.put(temp);
}
catch (JSONException e){
log("Not able to format JSON" + ": "+ e.toString());
}
StringRequest sr = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
//Code that verifies if the request is successfull and removes only the sent objects from the JSONArray.
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error){
//Code that Handles the error.
}
}){
#Override
protected Map<String, String> getParams(){
Map<String, String> params = new HashMap<>();
try {
params.put("data", json.put("data", arrJ).toString());
}catch (JSONException e){
e.printStackTrace();
}
return params;
}
};
queue.add(sr);
}
The problem I am facing is as follows: Once the GPSData has been recorded in the JSONArray, It is then picked up by the Network(Volley) Request thread and processed. Now because I don't know how long the request would take, I need to be able to get the sent Parameters in the getParams() function in the onResponse() function to be able to remove only the sent objects from the JSONArray to avoid duplication.
I am not sure if this is the correct implementation. If there is a better approach, I am definitely open to incorporating it into the app.
You can use this custom request ,
import com.android.volley.AuthFailureError;
import com.android.volley.Response;
import com.android.volley.toolbox.StringRequest;
import java.util.HashMap;
import java.util.Map;
/**
* #author Krish
*/
public class CustomRequest {
private Response.Listener<String> mOriginalListner;
private String requestData;
private StringRequest request;
public CustomRequest(int method, String json, String url, Response.Listener<String> listener, Response.ErrorListener errorListener) {
this.requestData = json;
this.mOriginalListner = listener;
init(method, url, mListener, errorListener);
}
private Response.Listener<String> mListener = new Response.Listener<String>() {
#Override
public void onResponse(String response) {
mOriginalListner.onResponse(requestData);
}
};
private void init(int method, String url, Response.Listener<String> listener, Response.ErrorListener errorListener) {
this.request = new StringRequest(method, url, listener, errorListener) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
try {
params.put("data", requestData);
} catch (Exception e) {
e.printStackTrace();
}
return params;
}
};
}
public StringRequest build() {
return request;
}
}
and you can use the response to remove the send objects.
Hi I know voley call sending parameter using Map
for ex
private void SignInWithEmail() {
//email= String.valueOf(mEmail.getText());
//pass = String.valueOf(mPassword.getText());
String url = RequestUrls.getInstance().signInByEmail();
StringRequest mRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.v(TAG, "Login with email" + response);
try {
JSONObject jsonResponse = new JSONObject(response);
String code = jsonResponse.getString("code");
if (code == "1") {
JSONArray UserDetailArray = jsonResponse.getJSONArray("document");
Log.v("Login with email", UserDetailArray.toString());
JSONObject finalObject = UserDetailArray.getJSONObject(0);
String User_email = finalObject.getString("Email");
getUserByEmail(User_email);
} else {
Toast.makeText(getApplicationContext(), "Invalid Email or Password", Toast.LENGTH_SHORT).show();
mPassword.setText("");
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.v(TAG, "Request for getUserByEmail Error: " + error.toString());
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("Action", "GetUserByEmail");
//Log.v("Login", "Action Email for put: " + email);
params.put("UserName", email);
params.put("Password", pass);
return params;
}
};
VolleySingleton.getInstance(getApplicationContext()).addToRequestQueue(mRequest);
}
but i have to send
this as parameter how to do that
{
"jsonrpc": "2.0",
"method": "signUp",
"id": "1",
"params": {
"email": "abc#gmail.com",
"fname": "abc",
"lname": "def",
"pwd": "123"
}
}
do i have to add header or any other method please suggest me.I am new in android development.
this the screen shot from postman chrome extension
please help me.
JsonObjectRequest jsObjRequest = new JsonObjectRequest
(Request.Method.POST, url, json, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// TODO Auto-generated method stub
}
});
you can send your json using the above code in the json paramter.
try
JSONObject jsonObject1 = new JSONObject();
try {
jsonObject1.put("email", "abc#gmail.com");
jsonObject1.put("fname", "abc");
jsonObject1.put("lname", "def");
jsonObject1.put("pwd", "123");
} catch (JSONException e) {
e.printStackTrace();
}
Map<String, String> postParam = new HashMap<>();
postParam.put("jsonrpc", "2.0");
postParam.put("method", "signUp");
postParam.put("id", "1");
postParam.put("params", jsonObject1.toString());
CustomRequest jsObjRequest = new CustomRequest(
Request.Method.POST,
URL,
postParam, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError arg0) {
}
});
mRequestQueue.add(jsObjRequest);
Happy code
import java.io.UnsupportedEncodingException;
import java.util.Map;
import org.json.JSONException;
import org.json.JSONObject;
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.toolbox.HttpHeaderParser;
public class CustomRequest extends Request<JSONObject> {
private Listener<JSONObject> listener;
private Map<String, String> params;
public CustomRequest(String url, Map<String, String> params,
Listener<JSONObject> reponseListener, ErrorListener errorListener) {
super(Method.GET, url, errorListener);
this.listener = reponseListener;
this.params = params;
}
public CustomRequest(int method, String url, Map<String, String> params,
Listener<JSONObject> reponseListener, ErrorListener errorListener) {
super(method, url, errorListener);
this.listener = reponseListener;
this.params = params;
}
protected Map<String, String> getParams()
throws com.android.volley.AuthFailureError {
return params;
};
#Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString = new String(response.data,
HttpHeaderParser.parseCharset(response.headers));
return Response.success(new JSONObject(jsonString),
HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JSONException je) {
return Response.error(new ParseError(je));
}
}
#Override
protected void deliverResponse(JSONObject response) {
// TODO Auto-generated method stub
listener.onResponse(response);
}
}
Use CustomRequest and pass your map in the argument.
Steps to Send Object/Model/POJO class to volley post request.
Step 1: Make sure your class should the parsable.
Step 2: Override the toString method in model class.
Step 3: Create map i.e Map<String, Object> params = new Map<String, Object>
();
JSONObject object = new JSONObject(classObject.toString())
params.put("key", object)
Step 4: Put the params with volley request.
I am using android Volley for making a request. So I use this code. I don't understand one thing. I check in my server that params is always null. I consider that getParams() not working. What should I do to solve this issue.
RequestQueue queue = MyVolley.getRequestQueue();
JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.POST,SPHERE_URL,null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
System.out.println(response);
hideProgressDialog();
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
hideProgressDialog();
}
}) {
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("id","1");
params.put("name", "myname");
return params;
};
};
queue.add(jsObjRequest);
try to use this helper class
import java.io.UnsupportedEncodingException;
import java.util.Map;
import org.json.JSONException;
import org.json.JSONObject;
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.toolbox.HttpHeaderParser;
public class CustomRequest extends Request<JSONObject> {
private Listener<JSONObject> listener;
private Map<String, String> params;
public CustomRequest(String url, Map<String, String> params,
Listener<JSONObject> reponseListener, ErrorListener errorListener) {
super(Method.GET, url, errorListener);
this.listener = reponseListener;
this.params = params;
}
public CustomRequest(int method, String url, Map<String, String> params,
Listener<JSONObject> reponseListener, ErrorListener errorListener) {
super(method, url, errorListener);
this.listener = reponseListener;
this.params = params;
}
protected Map<String, String> getParams()
throws com.android.volley.AuthFailureError {
return params;
};
#Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString = new String(response.data,
HttpHeaderParser.parseCharset(response.headers));
return Response.success(new JSONObject(jsonString),
HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JSONException je) {
return Response.error(new ParseError(je));
}
}
#Override
protected void deliverResponse(JSONObject response) {
// TODO Auto-generated method stub
listener.onResponse(response);
}
}
In activity/fragment do use this
RequestQueue requestQueue = Volley.newRequestQueue(getActivity());
CustomRequest jsObjRequest = new CustomRequest(Method.POST, url, params, this.createRequestSuccessListener(), this.createRequestErrorListener());
requestQueue.add(jsObjRequest);
You can create a custom JSONObjectReuqest and override the getParams method, or you can provide them in the constructor as a JSONObject to be put in the body of the request.
Like this (I edited your code):
JSONObject obj = new JSONObject();
obj.put("id", "1");
obj.put("name", "myname");
RequestQueue queue = MyVolley.getRequestQueue();
JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.POST,SPHERE_URL,obj,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
System.out.println(response);
hideProgressDialog();
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
hideProgressDialog();
}
});
queue.add(jsObjRequest);
Easy one for me ! I got it few weeks ago :
This goes in getBody() method, not in getParams() for a post request.
Here is mine :
#Override
/**
* Returns the raw POST or PUT body to be sent.
*
* #throws AuthFailureError in the event of auth failure
*/
public byte[] getBody() throws AuthFailureError {
// Map<String, String> params = getParams();
Map<String, String> params = new HashMap<String, String>();
params.put("id","1");
params.put("name", "myname");
if (params != null && params.size() > 0) {
return encodeParameters(params, getParamsEncoding());
}
return null;
}
(I assumed you want to POST the params you wrote in your getParams)
I gave the params to the request inside the constructor, but since you are creating the request on the fly, you can hard coded them inside your override of the getBody() method.
This is what my code looks like :
Bundle param = new Bundle();
param.putString(HttpUtils.HTTP_CALL_TAG_KEY, tag);
param.putString(HttpUtils.HTTP_CALL_PATH_KEY, url);
param.putString(HttpUtils.HTTP_CALL_PARAM_KEY, params);
switch (type) {
case RequestType.POST:
param.putInt(HttpUtils.HTTP_CALL_TYPE_KEY, RequestType.POST);
SCMainActivity.mRequestQueue.add(new SCRequestPOST(Method.POST, url, this, tag, receiver, params));
and if you want even more this last string params comes from :
param = JsonUtils.XWWWUrlEncoder.encode(new JSONObject(paramasJObj)).toString();
and the paramasJObj is something like this : {"id"="1","name"="myname"} the usual JSON string.
When you working with JsonObject request you need to pass the parameters right after you pass the link in the initialization , take a look on this code :
HashMap<String, String> params = new HashMap<>();
params.put("user", "something" );
params.put("some_params", "something" );
JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, "request_URL", new JSONObject(params), new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
// Some code
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//handle errors
}
});
}
All you need to do is to override getParams method in Request class. I had the same problem and I searched through the answers but I could not find a proper one. The problem is unlike get request, post parameters being redirected by the servers may be dropped. For instance, read this. So, don't risk your requests to be redirected by webserver. If you are targeting http://example/myapp , then mention the exact address of your service, that is http://example.com/myapp/index.php.
Volley is OK and works perfectly, the problem stems from somewhere else.
The override function getParams works fine. You use POST method and you have set the jBody as null. That's why it doesn't work. You could use GET method if you want to send null jBody.
I have override the method getParams and it works either with GET method (and null jBody) either with POST method (and jBody != null)
Also there are all the examples here
I had the same issue once, the empty POST array is caused due a redirection of the request (on your server side), fix the URL so it doesn't have to be redirected when it hits the server. For Example, if https is forced using the .htaccess file on your server side app, make sure your client request has the "https://" prefix. Usually when a redirect happens the POST array is lost. I Hope this helps!
It worked for can try this for calling with Volley Json Request and Response ith Java Code .
public void callLogin(String sMethodToCall, String sUserId, String sPass) {
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(
Request.Method.POST, ConstantValues.ROOT_URL_LOCAL + sMethodToCall.toString().trim(), addJsonParams(sUserId, sPass),
// JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, url, object,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d("onResponse", response.toString());
Toast.makeText(VolleyMethods.this, response.toString(), Toast.LENGTH_LONG).show(); // Test
parseResponse(response);
// msgResponse.setText(response.toString());
// hideProgressDialog();
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d("onErrorResponse", "Error: " + error.getMessage());
Toast.makeText(VolleyMethods.this, error.toString(), Toast.LENGTH_LONG).show();
// hideProgressDialog();
}
}) {
/**
* Passing some request headers
*/
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Content-Type", "application/json; charset=utf-8");
return headers;
}
};
requestQueue.add(jsonObjectRequest);
}
public JSONObject addJsonParams(String sUserId, String sPass) {
JSONObject jsonobject = new JSONObject();
try {
// {"id":,"login":"secretary","password":"password"}
///***//
Log.d("addJsonParams", "addJsonParams");
// JSONObject jsonobject = new JSONObject();
// JSONObject jsonobject_one = new JSONObject();
//
// jsonobject_one.put("type", "event_and_offer");
// jsonobject_one.put("devicetype", "I");
//
// JSONObject jsonobject_TWO = new JSONObject();
// jsonobject_TWO.put("value", "event");
// JSONObject jsonobject = new JSONObject();
//
// jsonobject.put("requestinfo", jsonobject_TWO);
// jsonobject.put("request", jsonobject_one);
jsonobject.put("id", "");
jsonobject.put("login", sUserId); // sUserId
jsonobject.put("password", sPass); // sPass
// js.put("data", jsonobject.toString());
} catch (JSONException e) {
e.printStackTrace();
}
return jsonobject;
}
public void parseResponse(JSONObject response) {
Boolean bIsSuccess = false; // Write according to your logic this is demo.
try {
JSONObject jObject = new JSONObject(String.valueOf(response));
bIsSuccess = jObject.getBoolean("success");
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(VolleyMethods.this, "" + e.toString(), Toast.LENGTH_LONG).show(); // Test
}
}
build gradle(app)
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.1.0'
implementation 'androidx.appcompat:appcompat:1.1.0-alpha01'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation 'com.android.volley:volley:1.1.1'
}
android manifest
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
MainActivity
When you use JsonObjectRequest it is mandatory to send a jsonobject and receive jsonobject otherwise you will get an error as it only accepts jsonobject.
import com.android.volley.Request
import com.android.volley.Response
import com.android.volley.toolbox.JsonObjectRequest
import com.android.volley.toolbox.Volley
fun peticion(){
val jsonObject = JSONObject()
jsonObject.put("user", "jairo")
jsonObject.put("password", "1234")
val queue = Volley.newRequestQueue(this)
val url = "http://192.168.0.3/get_user.php"
// GET: JsonObjectRequest( url, null,
// POST: JsonObjectRequest( url, jsonObject,
val jsonObjectRequest = JsonObjectRequest( url, jsonObject,
Response.Listener { response ->
// Check if the object 'msm' does not exist
if(response.isNull("msm")){
println("Name: "+response.getString("nombre1"))
}
else{
// If the object 'msm' exists we print it
println("msm: "+response.getString("msm"))
}
},
Response.ErrorListener { error ->
error.printStackTrace()
println(error.toString())
}
)
queue.add(jsonObjectRequest)
}
file php get_user.php
<?php
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: *");
// we receive the parameters
$json = file_get_contents('php://input');
$params = json_decode($json);
error_reporting(0);
require_once 'conexion.php';
$mysqli=getConex();
$user=$params->user;
$password=$params->password;
$res=array();
$verifica_usuario=mysqli_query($mysqli,"SELECT * FROM usuarios WHERE usuario='$user' and clave='$password'");
if(mysqli_num_rows($verifica_usuario)>0){
$query="SELECT * FROM usuarios WHERE usuario='$user'";
$result=$mysqli->query($query);
while($row = $result->fetch_array(MYSQLI_ASSOC)){
$res=$row;
}
}
else{
$res=array('msm'=>"Incorrect user or password");
}
$jsonstring = json_encode($res);
header('Content-Type: application/json');
echo $jsonstring;
?>
file php conexion
<?php
function getConex(){
$servidor="localhost";
$usuario="root";
$pass="";
$base="db";
$mysqli = mysqli_connect($servidor,$usuario,$pass,$base);
if (mysqli_connect_errno($mysqli)){
echo "Fallo al conectar a MySQL: " . mysqli_connect_error();
}
$mysqli->set_charset('utf8');
return $mysqli;
}
?>
I am developing an Android app where I need to fetch results from a MySQL database in a remote server. I have written some PHP scripts to query the database and output the results in JSON format.
The problem is that the request fetches expected results only for the first time. When I send the same request with different POST params, it returns the first result all over again. I modified the PHP script to attach the POST param in the JSON result and tried logging the POST param. It is also the same first param.
If I uninstall the app from the device and re-install, again it returns the correct JSON only for the first time.
NOTE: When i run the same code with the same PHP scripts and same database on localhost (WAMPP), everything works perfect.
I tried using the Google Chrome extension Postman to check the output from the remote server, it worked as expected. So, I can confirm that the problem is with my app/code.
Here's my CustomJSONObjectRequest class :
public class CustomJSONObjectRequest extends Request<JSONObject> {
private Listener<JSONObject> listener;
private Map<String, String> params;
public CustomJSONObjectRequest(String url, Map<String, String> params,
Listener<JSONObject> reponseListener, ErrorListener errorListener) {
super(Method.GET, url, errorListener);
this.listener = reponseListener;
this.params = params;
}
public CustomJSONObjectRequest(int method, String url, Map<String, String> params,
Listener<JSONObject> reponseListener, ErrorListener errorListener) {
super(method, url, errorListener);
this.listener = reponseListener;
this.params = params;
}
protected Map<String, String> getParams()
throws com.android.volley.AuthFailureError {
return params;
};
#Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString = new String(response.data,
HttpHeaderParser.parseCharset(response.headers));
return Response.success(new JSONObject(jsonString),
HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JSONException je) {
return Response.error(new ParseError(je));
}
}
#Override
protected void deliverResponse(JSONObject response) {
listener.onResponse(response);
}
}
And this is how I am sending the request :
String item_name = getIntent().getExtras().getString("item_name");
String url = getString(R.string.remote_server)+"fetch-item-list.php";
CustomJSONObjectRequest jsObjRequest = new CustomJSONObjectRequest(Request.Method.POST, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
Log.d("item name from intent extra", item_name); //intent extra
Log.d("response", response.toString()); //json response
Log.d("item name from response", response.getString("item_name")); //post parameter. This and the intent extra should be same
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(), error.toString(), Toast.LENGTH_SHORT).show();
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("item_name", item_name);
return params;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> header = new HashMap<String, String>();
header.put("Content-Type", "application/json; charset=utf-8");
return header;
}
};
MyVolleySingleton.getInstance(getApplicationContext()).addToRequestQueue(jsObjRequest);
This is the logcat :
D/item name from intent extra: apple
D/Response: {"data":[{"item_discount":"0.00","item_price":"50.00","unique_id":"181................
D/item name from response: orange
I think I found the solution
Looks like the JSON response was getting cached, so the response for the first request got cached and the next requests were never sent to the server. The cached JSON response was returned for every other requests.
All I had to do was disable caching.
I added the line jsObjRequest.setShouldCache(false); before adding it to the request queue.
jsObjRequest.setShouldCache(false);
MyVolleySingleton.getInstance(getApplicationContext()).addToRequestQueue(jsObjRequest);
Thanks to this question.
But I still do not get it why it worked on localhost without this setting.
I need to send a POST request to a server using the following JSON object format:
{"auth": {"tenantName": "<tenant>", "passwordCredentials": {"username": "<user>", "password": "<password>"}}}
to get an authentication token as response for subsequent requests:
{
access: {
token: {
issued_at: "2014-11-03T01:45:53.819103"
expires: "2014-11-03T02:45:53Z"
id: "686889ba4244432696aaac1d022f4973"
So far I'm just testing the connection with volley to see if I can get the proper response in a Toast:
public void loginRequest(){
String[] credentials = getSharedPrefs();
final String user = credentials[0];
final String pass = credentials[1];
final String url = credentials[2];
JSONObject login = new JSONObject();
JSONObject result = new JSONObject();
try {
JSONObject auth = login.getJSONObject("auth");
JSONObject tenantName = auth.getJSONObject("tenantName");
JSONObject passwordCredentials = auth.getJSONObject("passwordCredentials");
JSONObject username = passwordCredentials.getJSONObject("username");
JSONObject password = passwordCredentials.getJSONObject("password");
login.put("tenantName","");
login.put("username",user);
login.put("password",pass);
} catch (JSONException e) {
e.printStackTrace();
}
JsonObjectRequest getRequest = new JsonObjectRequest(Request.Method.POST, url, login,
new Response.Listener<JSONObject>()
{
#Override
public void onResponse(JSONObject response) {
// display response
// TO DO
Toast toast = Toast.makeText(Login.this,response.toString(),Toast.LENGTH_LONG);
toast.setGravity(Gravity.TOP|Gravity.CENTER_HORIZONTAL,0,120);
toast.show();
}
},
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(Login.this, error.getMessage(), Toast.LENGTH_LONG).show();
}
}
){
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("tenantName", "");
params.put("username", user);
params.put("password", pass);
return params;
}
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("Accept", "application/json");
params.put("Content-Type", "application/json");
return params;
}
};
RequestQueue queue = Volley.newRequestQueue(this);
queue.add(getRequest);
}
}
However I'm getting the following error:
E/Volley﹕ [893] NetworkDispatcher.run: Unhandled exception java.lang.RuntimeException: Bad URL
java.lang.RuntimeException: Bad URL
at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:147)
at com.android.volley.NetworkDispatcher.run(NetworkDispatcher.java:110)
Caused by: java.net.MalformedURLException: Protocol not found:
at java.net.URL.<init>(URL.java:176)
at java.net.URL.<init>(URL.java:125)
at com.android.volley.toolbox.HurlStack.performRequest(HurlStack.java:101)
at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:96)
at com.android.volley.NetworkDispatcher.run(NetworkDispatcher.java:110)
Any idea what I'm missing?
EDIT: I did some more digging and realised the error above was caused by a wrong getter on the string "url". I fixed that but now I get:
E/Volley﹕ [787] BasicNetwork.performRequest: Unexpected response code 400 for http://10.10.10.10:5000/v2.0/tokens
It seems the code is not sending JSON properly. For instance if I try to send anything other than aplication/json to the site using the Advanced Rest Client I also get 400 Bad Request
package com.example.wexindemo;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
import org.json.JSONException;
import org.json.JSONObject;
import com.android.volley.AuthFailureError;
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.toolbox.HttpHeaderParser;
public class JsonObjectPostRequest extends Request<JSONObject> {
private Map<String, String> mMap;
private String params;
private Listener<JSONObject> mListener;
public JsonObjectPostRequest(String url, Listener<JSONObject> listener,
ErrorListener errorListener, String params) {
super(Request.Method.POST, url, errorListener);
mListener = listener;
this.params = params;
}
public JsonObjectPostRequest(String url, Listener<JSONObject> listener,
ErrorListener errorListener, Map map) {
super(Request.Method.POST, url, errorListener);
mListener = listener;
mMap = map;
}
// #Override
// protected Map<String, String> getParams() throws AuthFailureError {
//
// return mMap;
//
// }
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<String, String>();
headers.put("Charset", "UTF-8");
headers.put("Content-Type", "application/x-javascript");
headers.put("Accept-Encoding", "gzip,deflate");
return headers;
}
#Override
public byte[] getBody() throws AuthFailureError {
return params == null ? super.getBody() : params.getBytes();
}
#Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString =
new String(response.data,
HttpHeaderParser.parseCharset(response.headers));
return Response.success(new JSONObject(jsonString),
HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JSONException je) {
return Response.error(new ParseError(je));
}
}
#Override
protected void deliverResponse(JSONObject response) {
mListener.onResponse(response);
}
}
ps:You try to use this class to send a post request
I made it work using a String:
final String json = "{\"auth\": {\"tenantName\": \""+tnt+"\", \"passwordCredentials\": {\"username\": \""+user+"\", \"password\": \""+pass+"\"}}}";
JSONObject login = null;
try {
login = new JSONObject(json);
} catch (JSONException e) {
e.printStackTrace();
}
However I still would like to know how to do it programatically using JSONObject to get to know the proper syntax. Any takers?