与Volley的POST请求

时间:2016-05-23 20:00:48

标签: android android-volley

我正在制作一个基本的移动应用程序来与nosql数据库进行交互。到目前为止,我使用Volley没有任何问题。我的数据库中有两个主要实体,它们都将所有属性存储为字符串。使用一个实体,Volley的GET和POST工作正常,但是对于另一个实体,GET请求可以工作但不是POST请求(某些参数为null)。

我遇到问题的页面旨在让用户编辑他/她已经放入的数据。我首先使用Volley GET请求填充它。工作正常,所有参数都正确显示。然后,如果用户更改数据并提交数据,则会使用POST请求提交,但由于某些参数为空,因此失败。

我已将错误(我认为)缩小到getParams()函数。常规和胜利者变量已填充,但所有其他变量都返回null。同样,我的所有变量都是字符串,因此它看起来不像是不兼容的数据类型。

这是我的代码:

    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;
}

这是API的代码,我在Python中做过。我可以使用curl测试或Postman应用程序手动POST,并且所有数据都已正确填充并保存在数据库中:

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

2 个答案:

答案 0 :(得分:0)

为您的案例尝试不同的语法和请求类型:

 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
                }
            }
        });

答案 1 :(得分:0)

我发现了错误。它最终与Volley代码本身没有任何关系;我所拥有的实际上是在工作。问题是我忘记了我已经注释掉了一些输入验证码,并且在这样做时,它并没有从这两个字段中获取文本。

在项目早期,我设置了输入验证,以便用户无法提交无效字符。我没有为日期字段设置,所以我评论了一些代码.....包括为每个字段调用getText()。toString()方法的行。所以它从来没有从这些领域中获取输入。回想起来这很明显....... :(

            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();
            }
        }
    });