问题
I'm making a basic mobile app to interact with a nosql database. So far, I've had no problems using Volley. I have two main entities in my database, and both are storing all of their attributes as strings. With one entity, Volley's GET and POST works fine, but with the other entity, the GET request works but not the POST request (some parameters are null).
The page I'm having trouble with is intended to let the user edit data he/she has already put in. I first populate it with a Volley GET request. That works fine, and all of the parameters display properly. Then, if the user alters the data and submits it, it is submitted with a POST request, which fails because some of the parameters are null.
I've narrowed the error down (I think) to the getParams() function. The generals and victors variables are populated, but all of the others come back as null. Again, all of my variables are strings, so it doesn't seem like an incompatible data type.
Here's the code I have:
RequestQueue queue = Volley.newRequestQueue(this);
StringRequest postRequest = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
if (response != null) {
try {
Toast.makeText(EditDeleteDetail.this, "Detail Updated", Toast.LENGTH_LONG).show();
} catch (Exception e) {
e.printStackTrace();
}
}
Log.e(TAG, response);
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
}
) {
@Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
params.put("generals", generals);
Log.d("Params generals", generals);
params.put("victor", victor);
Log.d("Params victor", victor);
params.put("ramifications", ramifications);
Log.d("Params ramifications", ramifications);
params.put("casualties", casualties);
Log.d("Params casualties", casualties);
params.put("startdate", startdate);
Log.d("Params startdate", startdate);
params.put("enddate", enddate);
return params;
}
};
queue.add(postRequest);
return true;
}
Here's the code for the API, which I did in Python. I can manually POST using curl tests or the Postman app, and all of the data is correctly populated and saved in the database:
import webapp2
from google.appengine.ext import ndb
import db_models
import json
class Detail(webapp2.RequestHandler):
def post(self, **kwargs):
"""Creates a Detail entity
POST Body Variables:
generals- String. List of commanding generals
victor - String. Winner (if any) of battle
ramifications - String. Results and implications of the battle
casualties - Stored as string, but also includes integers. Participating armies' casualties
startdate - Date property
enddate - Date property
"""
if 'application/json' not in self.request.accept:
self.response.status = 406
self.response.status_message = "Not Acceptable, API only supports application/json MIME type"
return
if 'did' in kwargs:
curr_det = ndb.Key(db_models.Details, int(kwargs['did'])).get()
generals = self.request.get('generals', default_value=None)
victor = self.request.get('victor', default_value=None)
ramifications = self.request.get('ramifications', default_value=None)
casualties = self.request.get('casualties', default_value=None)
startdate = self.request.get('startdate', default_value=None)
enddate = self.request.get('enddate', default_value=None)
if generals:
curr_det.generals = generals
if victor:
curr_det.victor = victor
if ramifications:
curr_det.ramifications = ramifications
if casualties:
curr_det.casualties = casualties
if startdate:
curr_det.startdate = startdate
if enddate:
curr_det.enddate = enddate
curr_det.put()
out = curr_det.to_dict()
self.response.write(json.dumps(out))
else:
new_detail = db_models.Details() #making a new Detail
generals = self.request.get('generals', default_value=None)
victor = self.request.get('victor', default_value=None)
ramifications = self.request.get('ramifications', default_value=None)
casualties = self.request.get('casualties', default_value=None)
startdate = self.request.get('startdate', default_value=None)
enddate = self.request.get('enddate', default_value=None)
if generals:
new_detail.generals = generals
else:
self.response.status = 400
self.response.status_message = "Invalid request, Commanding generals are Required"
return
if victor:
new_detail.victor = victor
if ramifications:
new_detail.ramifications = ramifications
if casualties:
new_detail.casualties = casualties
if startdate:
new_detail.startdate = startdate
if enddate:
new_detail.enddate = enddate
key = new_detail.put() #this saves the new Detail in the database
out = new_detail.to_dict() #then we return the thing we just made
self.response.write(json.dumps(out))
return
回答1:
Try a different syntax and Request type for your case:
Map<String, Object> jsonParams = new ArrayMap<>();
jsonParams.put("nodeId", null);
jsonParams.put("userId", null);
jsonParams.put("email", "some@gmail.com");
jsonParams.put("userProfile", null);
jsonParams.put("region", null);
jsonParams.put("password", 123);
jsonParams.put("places", new ArrayList());
JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, url, new JSONObject(jsonParams),
new Response.Listener<JSONObject>()
{
@Override
public void onResponse(JSONObject response)
{
//print it here and check
}
},
new Response.ErrorListener()
{
@Override
public void onErrorResponse(VolleyError error)
{
if (null != error.networkResponse)
{
//do whatever
}
}
});
回答2:
I found the error. It ended up not having anything to do with the Volley code itself; what I had was actually working. The problem was that I had forgotten that I commented out some of the input verification code, and in doing so, it wasn't picking up the text from those two fields.
Earlier on in the project, I had input verification set up so that users couldn't submit invalid characters. I didn't have that set up for the date fields, so I commented some of that code out.....including the lines that were calling the getText().toString() method for each field. So it literally was never pulling in the input from those fields. It's so obvious in retrospect....... :(
startdate = startDateEditText.getText().toString();
System.out.println(startdate);
if (!isValidDate(startdate)) {
startDateEditText.setError("Invalid input.");
isValidInput = false;
}
enddate = endDateEditText.getText().toString();
System.out.println(enddate);
if (!isValidDate(enddate)) {
endDateEditText.setError("Invalid input.");
isValidInput = false;
}
if (isValidInput) {
newPostRequest();
finish();
}
}
});
来源:https://stackoverflow.com/questions/37399526/post-request-with-volley