web-dev-qa-db-de.com

Senden Sie eine POST Anfrage mit JSON Daten mit Volley

Ich möchte eine neue JsonObjectRequest Anfrage senden:

  • Ich möchte JSON-Daten empfangen (Antwort vom Server): OK
  • Ich möchte mit dieser Anfrage JSON-formatierte Daten an den Server senden

    JsonObjectRequest request = new JsonObjectRequest(
        Request.Method.POST, "myurl.com", null,
        new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                //...
            }
        },
        new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                //...
            }
        })
        {
            @Override
            protected Map<String,String> getParams() {
                // something to do here ??
                return params;
            }
    
            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                // something to do here ??
                return params;
            }
        };
    

P.S. Ich benutze die GSON-Bibliothek auch in meinem Projekt.

81
anthony

JsonObjectRequest akzeptiert tatsächlich JSONObject als Hauptteil.

Von dieser Blogartikel ,

final String url = "some/url";
final JSONObject jsonBody = new JSONObject("{\"type\":\"example\"}");

new JsonObjectRequest(url, jsonBody, new Response.Listener<JSONObject>() { ... });

Hier ist der Quellcode und JavaDoc (@param jsonRequest):

/**
 * Creates a new request.
 * @param method the HTTP method to use
 * @param url URL to fetch the JSON from
 * @param jsonRequest A {@link JSONObject} to post with the request. Null is allowed and
 *   indicates no parameters will be posted along with request.
 * @param listener Listener to receive the JSON response
 * @param errorListener Error listener, or null to ignore errors.
 */
public JsonObjectRequest(int method, String url, JSONObject jsonRequest,
        Listener<JSONObject> listener, ErrorListener errorListener) {
    super(method, url, (jsonRequest == null) ? null : jsonRequest.toString(), listener,
                errorListener);
}
84
shkschneider

Ich weiß, dass dieser Thread ziemlich alt ist, aber ich hatte dieses Problem und fand eine coole Lösung, die für viele sehr nützlich sein kann, da sie die Volley-Bibliothek in vielen Punkten korrigiert/erweitert.

Ich habe einige nicht unterstützte Out-of-Box-Volley-Funktionen entdeckt:

  • Dieses JSONObjectRequest ist nicht perfekt: Sie müssen mit einem JSON am Ende rechnen (siehe das Response.Listener<JSONObject>).
  • Was ist mit leeren Antworten (nur mit einem 200-Status)?
  • Was mache ich, wenn ich mein POJO direkt vom ResponseListener haben möchte?

Ich habe mehr oder weniger viele Lösungen in einer großen Gattungsklasse zusammengestellt, um eine Lösung für alle von mir genannten Probleme zu finden.

  /**
  * Created by laurentmeyer on 25/07/15.
  */
 public class GenericRequest<T> extends JsonRequest<T> {

     private final Gson gson = new Gson();
     private final Class<T> clazz;
     private final Map<String, String> headers;
     // Used for request which do not return anything from the server
     private boolean muteRequest = false;

     /**
      * Basically, this is the constructor which is called by the others.
      * It allows you to send an object of type A to the server and expect a JSON representing a object of type B.
      * The problem with the #JsonObjectRequest is that you expect a JSON at the end.
      * We can do better than that, we can directly receive our POJO.
      * That's what this class does.
      *
      * @param method:        HTTP Method
      * @param classtype:     Classtype to parse the JSON coming from the server
      * @param url:           url to be called
      * @param requestBody:   The body being sent
      * @param listener:      Listener of the request
      * @param errorListener: Error handler of the request
      * @param headers:       Added headers
      */
     private GenericRequest(int method, Class<T> classtype, String url, String requestBody,
                           Response.Listener<T> listener, Response.ErrorListener errorListener, Map<String, String> headers) {
         super(method, url, requestBody, listener,
                 errorListener);
         clazz = classtype;
         this.headers = headers;
         configureRequest();
     }

     /**
      * Method to be called if you want to send some objects to your server via body in JSON of the request (with headers and not muted)
      *
      * @param method:        HTTP Method
      * @param url:           URL to be called
      * @param classtype:     Classtype to parse the JSON returned from the server
      * @param toBeSent:      Object which will be transformed in JSON via Gson and sent to the server
      * @param listener:      Listener of the request
      * @param errorListener: Error handler of the request
      * @param headers:       Added headers
      */
     public GenericRequest(int method, String url, Class<T> classtype, Object toBeSent,
                           Response.Listener<T> listener, Response.ErrorListener errorListener, Map<String, String> headers) {
         this(method, classtype, url, new Gson().toJson(toBeSent), listener,
                 errorListener, headers);
     }

     /**
      * Method to be called if you want to send some objects to your server via body in JSON of the request (without header and not muted)
      *
      * @param method:        HTTP Method
      * @param url:           URL to be called
      * @param classtype:     Classtype to parse the JSON returned from the server
      * @param toBeSent:      Object which will be transformed in JSON via Gson and sent to the server
      * @param listener:      Listener of the request
      * @param errorListener: Error handler of the request
      */
     public GenericRequest(int method, String url, Class<T> classtype, Object toBeSent,
                           Response.Listener<T> listener, Response.ErrorListener errorListener) {
         this(method, classtype, url, new Gson().toJson(toBeSent), listener,
                 errorListener, new HashMap<String, String>());
     }

     /**
      * Method to be called if you want to send something to the server but not with a JSON, just with a defined String (without header and not muted)
      *
      * @param method:        HTTP Method
      * @param url:           URL to be called
      * @param classtype:     Classtype to parse the JSON returned from the server
      * @param requestBody:   String to be sent to the server
      * @param listener:      Listener of the request
      * @param errorListener: Error handler of the request
      */
     public GenericRequest(int method, String url, Class<T> classtype, String requestBody,
                           Response.Listener<T> listener, Response.ErrorListener errorListener) {
         this(method, classtype, url, requestBody, listener,
                 errorListener, new HashMap<String, String>());
     }

     /**
      * Method to be called if you want to GET something from the server and receive the POJO directly after the call (no JSON). (Without header)
      *
      * @param url:           URL to be called
      * @param classtype:     Classtype to parse the JSON returned from the server
      * @param listener:      Listener of the request
      * @param errorListener: Error handler of the request
      */
     public GenericRequest(String url, Class<T> classtype, Response.Listener<T> listener, Response.ErrorListener errorListener) {
         this(Request.Method.GET, url, classtype, "", listener, errorListener);
     }

     /**
      * Method to be called if you want to GET something from the server and receive the POJO directly after the call (no JSON). (With headers)
      *
      * @param url:           URL to be called
      * @param classtype:     Classtype to parse the JSON returned from the server
      * @param listener:      Listener of the request
      * @param errorListener: Error handler of the request
      * @param headers:       Added headers
      */
     public GenericRequest(String url, Class<T> classtype, Response.Listener<T> listener, Response.ErrorListener errorListener, Map<String, String> headers) {
         this(Request.Method.GET, classtype, url, "", listener, errorListener, headers);
     }

     /**
      * Method to be called if you want to send some objects to your server via body in JSON of the request (with headers and muted)
      *
      * @param method:        HTTP Method
      * @param url:           URL to be called
      * @param classtype:     Classtype to parse the JSON returned from the server
      * @param toBeSent:      Object which will be transformed in JSON via Gson and sent to the server
      * @param listener:      Listener of the request
      * @param errorListener: Error handler of the request
      * @param headers:       Added headers
      * @param mute:          Muted (put it to true, to make sense)
      */
     public GenericRequest(int method, String url, Class<T> classtype, Object toBeSent,
                           Response.Listener<T> listener, Response.ErrorListener errorListener, Map<String, String> headers, boolean mute) {
         this(method, classtype, url, new Gson().toJson(toBeSent), listener,
                 errorListener, headers);
         this.muteRequest = mute;
     }

     /**
      * Method to be called if you want to send some objects to your server via body in JSON of the request (without header and muted)
      *
      * @param method:        HTTP Method
      * @param url:           URL to be called
      * @param classtype:     Classtype to parse the JSON returned from the server
      * @param toBeSent:      Object which will be transformed in JSON via Gson and sent to the server
      * @param listener:      Listener of the request
      * @param errorListener: Error handler of the request
      * @param mute:          Muted (put it to true, to make sense)
      */
     public GenericRequest(int method, String url, Class<T> classtype, Object toBeSent,
                           Response.Listener<T> listener, Response.ErrorListener errorListener, boolean mute) {
         this(method, classtype, url, new Gson().toJson(toBeSent), listener,
                 errorListener, new HashMap<String, String>());
         this.muteRequest = mute;

     }

     /**
      * Method to be called if you want to send something to the server but not with a JSON, just with a defined String (without header and not muted)
      *
      * @param method:        HTTP Method
      * @param url:           URL to be called
      * @param classtype:     Classtype to parse the JSON returned from the server
      * @param requestBody:   String to be sent to the server
      * @param listener:      Listener of the request
      * @param errorListener: Error handler of the request
      * @param mute:          Muted (put it to true, to make sense)
      */
     public GenericRequest(int method, String url, Class<T> classtype, String requestBody,
                           Response.Listener<T> listener, Response.ErrorListener errorListener, boolean mute) {
         this(method, classtype, url, requestBody, listener,
                 errorListener, new HashMap<String, String>());
         this.muteRequest = mute;

     }


     @Override
     protected Response<T> parseNetworkResponse(NetworkResponse response) {
         // The magic of the mute request happens here
         if (muteRequest) {
             if (response.statusCode >= 200 && response.statusCode <= 299) {
                 // If the status is correct, we return a success but with a null object, because the server didn't return anything
                 return Response.success(null, HttpHeaderParser.parseCacheHeaders(response));
             }
         } else {
             try {
                 // If it's not muted; we just need to create our POJO from the returned JSON and handle correctly the errors
                 String json = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
                 T parsedObject = gson.fromJson(json, clazz);
                 return Response.success(parsedObject, HttpHeaderParser.parseCacheHeaders(response));
             } catch (UnsupportedEncodingException e) {
                 return Response.error(new ParseError(e));
             } catch (JsonSyntaxException e) {
                 return Response.error(new ParseError(e));
             }
         }
         return null;
     }

     @Override
     public Map<String, String> getHeaders() throws AuthFailureError {
         return headers != null ? headers : super.getHeaders();
     }

     private void configureRequest() {
         // Set retry policy
         // Add headers, for auth for example
         // ...
     }
 }

Es könnte ein bisschen übertrieben wirken, aber es ist ziemlich cool, all diese Konstruktoren zu haben, weil Sie alle Fälle haben:

(Der Hauptkonstruktor sollte nicht direkt verwendet werden, obwohl dies natürlich möglich ist.).

  1. Anfrage mit Antwort geparst an POJO/Header manuell setzen/POJO auf Senden
  2. Anfrage mit geparster Antwort an POJO/POJO zum Senden
  3. Anforderung mit zu sendender Antwort an POJO/String geparst
  4. Anfrage mit geparster Antwort an POJO (GET)
  5. Anfrage mit Antwort geparst an POJO (GET)/Header manuell gesetzt
  6. Anfrage ohne Antwort (200 - Leerer Körper)/Header manuell setzen/POJO auf Senden
  7. Anfrage ohne Antwort (200 - Leerer Körper)/POJO zum Senden
  8. Anforderung ohne Antwort (200 - Leerer Text)/Zu sendende Zeichenfolge

Damit es funktioniert, müssen Sie natürlich Googles GSON Lib haben. einfach hinzufügen:

compile 'com.google.code.gson:gson:x.y.z'

zu Ihren Abhängigkeiten (aktuelle Version ist 2.3.1).

43
Laurent Meyer
final String URL = "/volley/resource/12";
// Post params to be sent to the server
HashMap<String, String> params = new HashMap<String, String>();
params.put("token", "AbCdEfGh123456");

JsonObjectRequest req = new JsonObjectRequest(URL, new JSONObject(params),
       new Response.Listener<JSONObject>() {
           @Override
           public void onResponse(JSONObject response) {
               try {
                   VolleyLog.v("Response:%n %s", response.toString(4));
               } catch (JSONException e) {
                   e.printStackTrace();
               }
           }
       }, new Response.ErrorListener() {
           @Override
           public void onErrorResponse(VolleyError error) {
               VolleyLog.e("Error: ", error.getMessage());
           }
       });

// add the request object to the queue to be executed
ApplicationController.getInstance().addToRequestQueue(req);

siehe

28
Issac Balaji
  • Erstellen Sie ein Objekt der Klasse RequestQueue.

    RequestQueue queue = Volley.newRequestQueue(this);
    
  • Erstellen Sie ein StringRequest mit Antwort- und Fehlerlistener.

     StringRequest sr = new StringRequest(Request.Method.POST,"http://api.someservice.com/post/comment", new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
            mPostCommentResponse.requestCompleted();
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            mPostCommentResponse.requestEndedWithError(error);
        }
    }){
        @Override
        protected Map<String,String> getParams(){
            Map<String,String> params = new HashMap<String, String>();
            params.put("user",userAccount.getUsername());
            params.put("pass",userAccount.getPassword());
            params.put("comment", Uri.encode(comment));
            params.put("comment_post_ID",String.valueOf(postId));
            params.put("blogId",String.valueOf(blogId));
    
            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;
        }
    };
    
  • Fügen Sie Ihre Anfrage in das RequestQueue ein.

    queue.add(jsObjRequest);
    
  • Erstellen Sie die PostCommentResponseListener Schnittstelle, damit Sie sie sehen können. Es ist ein einfacher Delegat für die asynchrone Anforderung.

    public interface PostCommentResponseListener {
    public void requestStarted();
    public void requestCompleted();
    public void requestEndedWithError(VolleyError error);
    }
    
  • Fügen Sie die INTERNET-Berechtigung in die Datei AndroidManifest.xml Ein.

    <uses-permission Android:name="Android.permission.INTERNET"/>
    
10
The Holy Coder
    final String url = "some/url";

anstatt von:

    final JSONObject jsonBody = "{\"type\":\"example\"}";

sie können verwenden:

  JSONObject jsonBody = new JSONObject();
    try {
        jsonBody.put("type", "my type");
    } catch (JSONException e) {
        e.printStackTrace();
    }
new JsonObjectRequest(url, jsonBody, new Response.Listener<JSONObject>() { ... });
3
Victor Odiah

Sie können Daten auch senden, indem Sie die getBody() -Methode der JsonObjectRequest -Klasse überschreiben. Wie nachfolgend dargestellt.

    @Override
    public byte[] getBody()
    {

        JSONObject jsonObject = new JSONObject();
        String body = null;
        try
        {
            jsonObject.put("username", "user123");
            jsonObject.put("password", "Pass123");

            body = jsonObject.toString();
        } catch (JSONException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        try
        {
            return body.toString().getBytes("utf-8");
        } catch (UnsupportedEncodingException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
1
DjP
final Map<String,String> params = new HashMap<String,String>();
        params.put("email", customer.getEmail());
        params.put("password", customer.getPassword());
        String url = Constants.BASE_URL+"login";

doWebRequestPost(url, params);


public void doWebRequestPost(String url, final Map<String,String> json){
        getmDialogListener().showDialog();

    StringRequest post = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
            try {
                getmDialogListener().dismissDialog();
                response....

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            Log.d(App.TAG,error.toString());
            getmDialogListener().dismissDialog();

        }
    }){
        @Override
        protected Map<String, String> getParams() throws AuthFailureError {
            Map<String,String> map = json;

            return map;
        }
    };
    App.getInstance().getRequestQueue().add(post);

}
1
vrbsm
protected Map<String, String> getParams() {
   Map<String, String> params = new HashMap<String, String>();

   JSONObject JObj = new JSONObject();

   try {
           JObj.put("Id","1");
           JObj.put("Name", "abc");

   } catch (Exception e) {
       e.printStackTrace();
   }

   params.put("params", JObj.toString());
   // Map.Entry<String,String>
   Log.d("Parameter", params.toString());
   return params;
}
0
Haresh Baraiya