Передать параметр с помощью записи Volley

#android #android-volley #azure-functions

#Android #android-volley #azure-функции

Вопрос:

Я смог вызвать конечную точку HTTP, используя Postman и эти параметры:

 {
    "name":"Val",
    "subject":"Test"
}
  

Однако я не могу сделать то же самое с Volley через Android: здесь я пытаюсь использовать JSONRequest:

 HashMap<String, String> params2 = new HashMap<String, String>();
        params.put("name", "Val");
        params.put("subject", "Test Subject");

        JsonObjectRequest jsObjRequest = new JsonObjectRequest
                (Request.Method.POST, Constants.CLOUD_URL, new JSONObject(params2), new Response.Listener<JSONObject>() {

                    @Override
                    public void onResponse(JSONObject response) {
                        mView.showMessage("Response: "   response.toString());
                    }
                }, new Response.ErrorListener() {

                    @Override
                    public void onErrorResponse(VolleyError error) {
                        // TODO Auto-generated method stub
                        mView.showMessage(error.getMessage());

                    }
                });

        // Access the RequestQueue through your singleton class.
        VolleySingleton.getInstance(mContext).addToRequestQueue(jsObjRequest);
  

И вот пытаюсь выполнить StringRequest

 private void postMessage(Context context, final String name, final String subject ){

        RequestQueue queue = Volley.newRequestQueue(context);
        StringRequest sr = new StringRequest(Request.Method.POST, Constants.CLOUD_URL, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                mView.showMessage(response);
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {

            }
        }){
            @Override
            protected Map<String,String> getParams(){
                Map<String,String> params = new HashMap<String, String>();
                params.put("name", name);
                params.put("subject", subject);

                return params;
            }

            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                Map<String,String> params = new HashMap<String, String>();
                params.put("Content-Type","application/x-www-form-urlencoded");
                return params;
            }
        };
        queue.add(sr);
    }
  

Когда я использую JSONRequest, вызов отправляется, но параметр не передается, и когда я использую StringRequest, я получаю сообщение об ошибке ниже? Как я могу передать данные JSON в Volley call?

 E/Volley: [13053] BasicNetwork.performRequest: Unexpected response code 400 for 
  

Вот код сервера, который обрабатывает запрос

 public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
    var helloRequest = await req.Content.ReadAsAsync<HelloRequest>();

    var name = helloRequest?.Name ?? "world";    
    var responseMessage = $"Hello {personToGreet}!";


    log.Info($"Message: {responseMessage}");


    return req.CreateResponse(HttpStatusCode.OK, $"All went well.");
}

public class HelloRequest
{
    public string Name { get; set; }
    public string Subject { get; set; }
}
  

Комментарии:

1. Принимает ли сервер формы в формате JSON или URL? new JSONObject(params2) это правильный способ использования JSONObjectRequest . Вы StringRequest не передаете данные JSON. Посмотрите на Content-Type getHeaders()

2. Можете ли вы также показать нам ту часть вашего сервера, где вы обрабатываете POST-запрос? Ваш POST-запрос JSONObject выглядит нормально.

3. Я добавил серверный код, который обрабатывает этот запрос.

Ответ №1:

Серверный код ожидает, что объект JSON возвращает строку или, скорее, строку Json.

JsonObjectRequest

JSONRequest отправляет объект JSON в теле запроса и ожидает объект JSON в ответе. Поскольку сервер возвращает строку, он в конечном итоге выдает ParseError

StringRequest

StringRequest отправляет запрос с типом тела x-www-form-urlencoded , но поскольку сервер ожидает объект JSON. В итоге вы получаете 400 неверных запросов

Решение

Решение состоит в том, чтобы изменить тип содержимого в строковом запросе на JSON, а также передать объект JSON в теле. Поскольку он уже ожидает строку, на которую вы отвечаете, у вас все хорошо. Код для этого должен быть следующим.

 StringRequest sr = new StringRequest(Request.Method.POST, Constants.CLOUD_URL, new Response.Listener<String>() {
    @Override
    public void onResponse(String response) {
        mView.showMessage(response);
    }
}, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
        mView.showMessage(error.getMessage());
    }
}) {
    @Override
    public byte[] getBody() throws AuthFailureError {
        HashMap<String, String> params2 = new HashMap<String, String>();
        params2.put("name", "Val");
        params2.put("subject", "Test Subject");
        return new JSONObject(params2).toString().getBytes();
    }

    @Override
    public String getBodyContentType() {
        return "application/json";
    }
};
  

Также здесь есть ошибка в коде сервера

 var responseMessage = $"Hello {personToGreet}!";
  

Должно быть

 var responseMessage = $"Hello {name}!";
  

Комментарии:

1. как добавить список строк в метод getParams() с использованием volley? В моем случае мне нужно добавить параметры одной строки и один список строк. пожалуйста, помогите мне

Ответ №2:

Добавьте тип содержимого в заголовок

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

Ответ №3:

Вы используете params.put вместо params2.put в вашей хэш-карте при передаче параметров. потому что имя вашего объекта — params2