android volley posting binary body

早过忘川 提交于 2019-12-31 04:32:49

问题


Scenario - upload binary data in the body of a post, handle a response body containing JSON.

How to do the following using Volley?

 curl -X  POST  -H "X-Application-Id: 3KxPB" -H "X-REST-API-Key: jkuI9"  -H "Content-Type: audio/3gp"  --data-binary '@test.3gp' https://host/1/files/audio

IMO - there is a gap in Volley handling binary POST body types that apache httpclient handles in subclasses of abstracthttpentity. If buffered binary data generated on the phone by camera, microphone, or other binary output sensors needs a mechanism to be wrapped and written to the body of a POST how to do it in volley?

I've looked at PoolingByteArrayOutputStream and would like to do something like fill the buffer and get the PBAOutStrm ,writing to PBAOutStrm from the buffer and then flipping OutStrm to InputStream and then wrap it in the body of a POST request as something like a ByteArrayEntity. I cant see how to do that in volley.


回答1:


To send binary data you can do something like what I did in this answer How to send a “multipart/form-data” POST in Android with Volley .




回答2:


I was able to solve this using a Volley GsonRequest:

public class MainActivity extends AppCompatActivity {


    String url = "https://arcane-anchorage-34204.herokuapp.com/handleCode";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        JSONObject jsonBody = null;
        try {
            jsonBody = new JSONObject ("{\"code\":\"NZ4UBUB\"}");
        } catch (JSONException e) {
            Toast.makeText(getApplicationContext(), "Error e = " + e, Toast.LENGTH_SHORT).show();
        }

        Map<String, String> headers = new HashMap<String, String>();
        headers.put("Content-Type", "application/json");

        RequestQueue queue = Volley.newRequestQueue(this);

        GsonRequest<Routine[]> gsonRequest = new GsonRequest<Routine[]>(Request.Method.POST, url, Routine[].class, headers, new Response.Listener<Routine[]>() {
            @Override
            public void onResponse(Routine[] routineData) {
                TextView serverData = (TextView)findViewById(R.id.serverData);

                String complete = "";
                String repeat = "";
                String hold = "";
                String perform = "";
                String txtData = "";

                for (int i = 0; i < routineData.length; i++) {
                    complete = (routineData[i].instructions.complete != null) ? "Complete: " + routineData[i].instructions.complete : "";
                    repeat = (routineData[i].instructions.repeat != null) ? "Repeat: " + routineData[i].instructions.repeat : "";
                    hold = (routineData[i].instructions.hold != null) ? "Hold: " + routineData[i].instructions.hold : "";
                    perform = (routineData[i].instructions.perform != null) ? "Perform: " + routineData[i].instructions.perform : "";

                    txtData += "DESCRIPTION: " + routineData[i].description[0] + ": " + routineData[i].description[1] + ", " + complete  + ", " + repeat  + ", " + hold  + ", " + perform + " ";
                }
                serverData.setText("Response: " + txtData);
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError volleyError) {
                TextView serverData = (TextView)findViewById(R.id.serverData);

                serverData.setText("Response: " + volleyError.toString());

            }
        }, jsonBody);
        queue.add(gsonRequest);
    }
    public class GsonRequest<T> extends Request<T> {
        private final Gson gson = new Gson();
        private final Class<T> clazz;
        private final Map<String, String> headers;
        private final Response.Listener<T> listener;
        private JSONObject parameters = null;

        /**
         * Make a GET request and return a parsed object from JSON.
         *
         * @param url URL of the request to make
         * @param clazz Relevant class object, for Gson's reflection
         * @param headers Map of request headers
         */
        public GsonRequest(int method, String url, Class<T> clazz, Map<String, String> headers,
                           Response.Listener<T> listener, Response.ErrorListener errorListener) {
            super(method, url, errorListener);
            this.clazz = clazz;
            this.headers = headers;
            this.listener = listener;
        }

        public GsonRequest(int method, String url, Class<T> clazz, Map<String, String> headers,
                           Response.Listener<T> listener, Response.ErrorListener errorListener, JSONObject parameters) {
            this(method, url, clazz, headers, listener, errorListener);
            this.parameters = parameters;
        }

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

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

        @Override
        public byte[] getBody() throws AuthFailureError {
            try {
                return parameters.toString().getBytes(getParamsEncoding());
            } catch (UnsupportedEncodingException e) {
            }
            return null;
        }

        @Override
        protected void deliverResponse(T response) {
            listener.onResponse(response);
        }

        @Override
        protected Response<T> parseNetworkResponse(NetworkResponse response) {
            try {
                String json = new String(
                        response.data, HttpHeaderParser.parseCharset(response.headers));
                Log.i("RESPONSE", json);
                return Response.success(
                        gson.fromJson(json, clazz), HttpHeaderParser.parseCacheHeaders(response));
            } catch (UnsupportedEncodingException e) {
                return Response.error(new ParseError(e));
            } catch (JsonSyntaxException e) {
                return Response.error(new ParseError(e));
            }
        }
      }
    }


来源:https://stackoverflow.com/questions/17382385/android-volley-posting-binary-body

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!