Search code examples
androidexceptionandroid-volleyeconnreset

Android Volley ECONNRESET


I try to use Volley library and upload image to server. This library should do this process in standalone mode, but have got following error message:

java.net.SocketException: sendto failed: ECONNRESET (Connection reset by peer)

Is it maybe a server side misconfiguration? I try to upload a jpeg image with this code:

private void uploadImage(){
    final ProgressDialog loading = ProgressDialog.show(this,"Uploading...","Please wait...",false,false);
    StringRequest stringRequest = new StringRequest(Request.Method.POST, UPLOAD_URL,
            new Response.Listener<String>() {
                @Override
                public void onResponse(String s) {
                    loading.dismiss();
                    Toast.makeText(PhotoActivity.this, s , Toast.LENGTH_LONG).show();
                }
            },
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError volleyError) {
                    loading.dismiss();

                    Toast.makeText(PhotoActivity.this, volleyError.getMessage().toString(), Toast.LENGTH_LONG).show();
                }
            }){
        @Override
        protected Map<String, String> getParams() throws AuthFailureError {
            String image = getStringImage(bitmap);
            String name = editTextName.getText().toString().trim();

            Map<String,String> params = new Hashtable<String, String>();

            params.put(KEY_IMAGE, image);
            params.put(KEY_NAME, name);

            return params;
        }
    };
    RequestQueue requestQueue = Volley.newRequestQueue(this);
    requestQueue.add(stringRequest);
}

Solution

  • just to be sure, you need to change your uploadImage() into something like this:

    private void uploadImage(){
        final ProgressDialog loading = ProgressDialog.show(this,"Uploading...","Please wait...",false,false);
        //here you use your custom multi-part-request as I suggested in the comment:
        ImageUploadRequest imageUploadReq = new ImageUploadRequest(UPLOAD_URL,            
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError volleyError) {
                        loading.dismiss();
    
                        Toast.makeText(PhotoActivity.this, volleyError.getMessage().toString(), Toast.LENGTH_LONG).show();
                    }
                },
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String s) {
                        loading.dismiss();
                        Toast.makeText(PhotoActivity.this, s , Toast.LENGTH_LONG).show();
                    }
                }, yourImageFile);
    
        RequestQueue requestQueue = Volley.newRequestQueue(this);
        requestQueue.add(imageUploadReq);
    }
    

    Where your ImageUploadRequest class is defined as demonstrated in the accepted answer here like this:

    public class ImageUploadRequest<T> extends Request<T> {
    
    private static final String FILE_PART_NAME = "file";
    
    private MultipartEntityBuilder mBuilder = MultipartEntityBuilder.create();
    private final Response.Listener<T> mListener;
    private final File mImageToUpload;
    protected Map<String, String> headers;
    
    public ImageUploadRequest(String uploadURL, ErrorListener errorListener, Listener<T> listener, File imageFileToUpload){
        super(Method.POST, uploadURL, errorListener);
    
        mListener = listener;
        mImageToUpload = imageFileToUpload;
        //call the helper method to build the multipart entity
        buildMultipartEntity();
    }
    
    @Override
    public Map<String, String> getHeaders() throws AuthFailureError {
        Map<String, String> headers = super.getHeaders();
    
        if (headers == null || headers.equals(Collections.emptyMap())) {
            headers = new HashMap<String, String>();
        }
    
        headers.put("Accept", "application/json");
    
        return headers;
    }
    
    private void buildMultipartEntity(){
        mBuilder.addBinaryBody(FILE_PART_NAME, mImageToUpload, ContentType.create("image/jpeg"), mImageToUpload.getName());
        mBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
        mBuilder.setLaxMode().setBoundary("xx").setCharset(Charset.forName("UTF-8"));
    }
    
    @Override
    public String getBodyContentType(){
        String contentTypeHeader = mBuilder.build().getContentType().getValue();
        return contentTypeHeader;
    }
    
    @Override
    public byte[] getBody() throws AuthFailureError{
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try {
            mBuilder.build().writeTo(bos);
        } catch (IOException e) {
            VolleyLog.e("IOException writing to ByteArrayOutputStream bos, building the multipart request.");
        }
    
        return bos.toByteArray();
    }
    
    @Override
    protected Response<T> parseNetworkResponse(NetworkResponse response) {
        T result = null;
        return Response.success(result, HttpHeaderParser.parseCacheHeaders(response));
    }
    
    @Override
    protected void deliverResponse(T response) {
        mListener.onResponse(response);
    }
    }
    

    I have made some minor adaptations of Upload an image using Google Volley to your specific situation. I hope this helps you and that others may also find it useful.