Search code examples
androidjsonapiandroid-volleymultipart

need first volley request response to make json object for second request


I have a big problem with volley request sequence and making json array out of first request response for second request.

this is the code :

    JSONObject imageAddedResponse = new JSONObject();
    JSONArray imagesAddedResponse = new JSONArray();

public void postImageData(Context applicationContext, String title, String note, ArrayList<ContentData> mImages, String videoPath, final Listeners.APIPostDataListener listener) {

    //Instantiate the RequestQueue.
    RequestQueue requestQueue = Volley.newRequestQueue(applicationContext);

    Settings settings = new Settings(applicationContext);
    String selectedURL = settings.getChosenUrl();
    final String token = settings.getTokenKey();
    String url = "http://" + selectedURL + "/databox/api/v1/upload/files";
    HashMap<String, String> params = new HashMap<String, String>();
    params.put("Authorization", "Bearer " + token);
    params.put("Content-Disposition", "form-data" + "; charset=utf-8");

    //POST data to CMS to get JSONObject back
    for (int i = 0; i < mImages.size(); i++) {
        String path = String.valueOf(mImages.get(i).getPath());
        File file = new File(path);
            MultipartRequest request = new MultipartRequest(url, file, Response.class, params, new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    if (listener != null) {
                        listener.onAPIPostData(String.valueOf(response), true);
                    }
                    if (response != null || response != "") {
                        try {
                            imageAddedResponse = new JSONObject(response);
                            JSONObject jsonArraydata = imageAddedResponse.getJSONObject("data");
                            JSONArray jsonArrayImages = jsonArraydata.getJSONArray("images");
                            imagesAddedResponse.put(jsonArrayImages);

                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    Log.e("Volley Request Error", error.toString());
                    if (listener != null) {
                        listener.onAPIPostData("", false);
                    }
                }
            });
            requestQueue.add(request);
    }

    //POST request to add entity to CMS
    JSONObject jsonimages = new JSONObject();
    JSONArray jsonArrayimages = new JSONArray();
    for (int i = 0 ; i < imagesAddedResponse.length() ; i++){
        try {
            JSONObject getObjectValues = imagesAddedResponse.getJSONObject(i);
            jsonimages.put("id",getObjectValues.getString("id"));
            jsonimages.put("src",getObjectValues.getString("src"));
            jsonimages.put("size",getObjectValues.getString("size"));
            jsonimages.put("baseName",getObjectValues.getString("baseName"));
            jsonimages.put("type",getObjectValues.getString("type"));
            jsonimages.put("db_languages_id", "1");
            jsonimages.put("title",String.valueOf(mImages.get(i).getTitle()));              
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    JSONObject json = new JSONObject();
    JSONArray jsonArray = new JSONArray();
    JSONObject finalobject = new JSONObject();
    try {
        json.put("title", title);
        json.put("description", note);
        json.put("db_languages_id", "1");
        json.put("db_user_id", "3");
        jsonArray.put(json);
        finalobject.put("data", jsonArray);
    } catch (JSONException e) {
        e.printStackTrace();
    }
    String urlFinal = "http://" + selectedURL + "/databox/api/v1/1/entity";
    JsonObjectRequest postRequest = new JsonObjectRequest(urlFinal, json, new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) {
            // response
            if (listener != null) {
                listener.onAPIPostData(String.valueOf(response), true);
            }
        }
    },
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    // TODO Auto-generated method stub
                    if (listener != null) {
                        listener.onAPIPostData("", false);
                    }
                }
            }
    ) {
        @Override
        public Map<String, String> getHeaders() throws AuthFailureError {
            Map<String, String> params = new HashMap<String, String>();
            params.put("Authorization", "Bearer " + token);
            params.put("Content-Type", "application/json; charset=utf-8");
            return params;
        }
    };
    postRequest.setShouldCache(false);
    requestQueue.add(postRequest);
}

first request post to CMS and get some information for images posted and then I need to add those information to next post to make entity based on response I got back from first post request.


Solution

  • int totalSuccesfulImagePost = 0; //this variable increment when each succesful response from multipart-request
    
    public void postImageData(Context applicationContext, String title, String note, ArrayList<ContentData> mImages, String videoPath, final Listeners.APIPostDataListener listener) {
    
          //Instantiate the RequestQueue.
          RequestQueue requestQueue = Volley.newRequestQueue(applicationContext);
    
          Settings settings = new Settings(applicationContext);
          String selectedURL = settings.getChosenUrl();
          final String token = settings.getTokenKey();
          String url = "http://" + selectedURL + "/databox/api/v1/upload/files";
          HashMap<String, String> params = new HashMap<String, String>();
          params.put("Authorization", "Bearer " + token);
          params.put("Content-Disposition", "form-data" + "; charset=utf-8");
    
          //POST data to CMS to get JSONObject back
          for (int i = 0; i < mImages.size(); i++) {
              String path = String.valueOf(mImages.get(i).getPath());
              File file = new File(path);
              MultipartRequest request = new MultipartRequest(url, file, Response.class, params, new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    if (listener != null) {
                        listener.onAPIPostData(String.valueOf(response), true);
                    }
                    if (response != null || response != "") {
                        try {
                            imageAddedResponse = new JSONObject(response);
                            JSONObject jsonArraydata = imageAddedResponse.getJSONObject("data");
                            JSONArray jsonArrayImages = jsonArraydata.getJSONArray("images");
                            imagesAddedResponse.put(jsonArrayImages.getJSONObject(0));
                            totalSuccesfulImagePost++; //here we increase the count
                            postRequest(token); //call this method and check wheather all the image uploaded or not
    
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    Log.e("Volley Request Error", error.toString());
                    if (listener != null) {
                        listener.onAPIPostData("", false);
                    }
                }
            });
            requestQueue.add(request);
       }
    }
    
    //make this as seperate method and call when all multipart-request call succesful
    public void postRequest(String token){
    
        if(totalSuccesfulImagePost != mImages.size()) {
            //this means not all the images posted yet, hence return the method
            return;
        }
    
        //POST request to add entity to CMS
        JSONObject jsonimages = new JSONObject();
        JSONArray jsonArrayimages = new JSONArray();
        for (int i = 0 ; i < imagesAddedResponse.length() ; i++){
            try {
            JSONObject getObjectValues = imagesAddedResponse.getJSONObject(i);
            jsonimages.put("id",getObjectValues.getString("id"));
            jsonimages.put("src",getObjectValues.getString("src"));
            jsonimages.put("size",getObjectValues.getString("size"));
                jsonimages.put("baseName",getObjectValues.getString("baseName"));
                jsonimages.put("type",getObjectValues.getString("type"));
                jsonimages.put("db_languages_id", "1");
                jsonimages.put("title",String.valueOf(mImages.get(i).getTitle()));              
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    
        JSONObject json = new JSONObject();
        JSONArray jsonArray = new JSONArray();
        JSONObject finalobject = new JSONObject();
        try {
            json.put("title", title);
            json.put("description", note);
            json.put("db_languages_id", "1");
            json.put("db_user_id", "3");
            jsonArray.put(json);
            finalobject.put("data", jsonArray);
        } catch (JSONException e) {
            e.printStackTrace();.getJSONObject(0)
        }
        String urlFinal = "http://" + selectedURL + "/databox/api/v1/1/entity";
        JsonObjectRequest postRequest = new JsonObjectRequest(urlFinal, json, new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                // response
                if (listener != null) {
                    listener.onAPIPostData(String.valueOf(response), true);
                }
            }
        },
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    // TODO Auto-generated method stub
                    if (listener != null) {
                        listener.onAPIPostData("", false);
                    }
                }
            }
    ) {
        @Override
        public Map<String, String> getHeaders() throws AuthFailureError {
            Map<String, String> params = new HashMap<String, String>();
            params.put("Authorization", "Bearer " + token);
            params.put("Content-Type", "application/json; charset=utf-8");
            return params;
        }
    };
        postRequest.setShouldCache(false);
        requestQueue.add(postRequest);
    }
    

    updated your code. Hope this may help you.

    1. I've created new method for JsonObjectRequest with the name postRequest();
    2. totalSuccesfulImagePost variable holds the no. of succesfull response for image upload
    3. new method postRequest() calls at each multipart-request response
    4. postRequest() methods check if not all response process yet than skip the 2nd api call

    Also see how fb do this batch request https://developers.facebook.com/docs/android/graph/ -> Batch Reqest

    Note -

    1. Ive increment the variable totalSuccesfulImagePost and handle in each response, although you need to Response.ErrorListener()

    2. Although you can go with the ThreadPoolExecutor option where each thread is created to handle each multipart-request upload and after all thread execution , call the method postRequest()

    Work-around using ThreadPoolExecutor

    a) Create ThreadPoolExecutor & initialize min/max pool size

    b) Asign each mulitpart-request to upload image to each thread

    c) Add all thread (contain image upload multipart-request) to ThreadPoolExecutor

    d) Execute pool

    e) call postRequest() method when ThreadPoolExecutor is empty i.e. this means all the thread execution is done and ready to call postRequest()