MultipartEntityBuilder to send data from Android h

2019-07-04 21:47发布

问题:

i am trying to change HTTPClient deprecated code but i get error on setEntity because its dapricated and i dont know how to paas MultipartEntityBuilder by new httpConnectionUrl. my old deprecated code snippt

    try {
        HttpClient client = new DefaultHttpClient();
        HttpPost post = new HttpPost(imagePostUrl);

        for (String fileName : fileNameArrayList) {

            File file = new File(fileName);
            // 1st

            int quality = GeneralUtil.getQualityOfImage(file);

            ByteArrayOutputStream bos = new ByteArrayOutputStream();

            if (quality <= 25) { // This means image file size is in MB's so we need to avoide out of memory issues.

                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inJustDecodeBounds = false;
                options.inPreferredConfig = Bitmap.Config.RGB_565;
                options.inDither = true;
                try {
                    bitmap = BitmapFactory.decodeFile(file.getPath(), options);
                } catch (OutOfMemoryError E) {
                    System.gc();
                    bitmap = GeneralUtil.decodeFile(file);

                }

                bitmap.compress(CompressFormat.JPEG, quality, bos);
                bitmap.recycle();
                bitmap = null;

            } else {

                try {
                    bitmap = BitmapFactory.decodeFile(file.getPath());
                    bitmap.compress(CompressFormat.JPEG, quality, bos);
                    bitmap.recycle();
                    bitmap = null;
                } catch (OutOfMemoryError E) {
                    System.gc();

                    try {
                        BitmapFactory.Options options = new BitmapFactory.Options();
                        options.inJustDecodeBounds = false;
                        options.inPreferredConfig = Bitmap.Config.RGB_565;
                        options.inDither = true;

                        bitmap = BitmapFactory.decodeFile(file.getPath(), options);
                        bitmap.compress(CompressFormat.JPEG, quality, bos);
                        bitmap.recycle();
                        bitmap = null;
                    } catch (OutOfMemoryError ex) {

                        bitmap = GeneralUtil.decodeFile(file);
                        bitmap.compress(CompressFormat.JPEG, quality, bos);
                        bitmap.recycle();
                        bitmap = null;
                        throw new Exception();
                    }
                }
            }

            byte[] data = bos.toByteArray();
            String timeStamp = GeneralUtil.generateTimeStamp();
            ByteArrayBody bin = new ByteArrayBody(data, myMobileNo + "_" + userName + "_" + timeStamp + ".jpg");

            MultipartEntityBuilder multiPartEntityBuilder = MultipartEntityBuilder.create();
            multiPartEntityBuilder.addPart("uploadedfile1", bin);
            multiPartEntityBuilder.addPart("inviteId", new StringBody(inviteIdArrayList.get(0).toString(), Charset.forName("UTF-8")));
            post.setEntity(multiPartEntityBuilder.build());
            HttpResponse httpResponse = null;
            httpResponse = client.execute(post);
            InputStream inputStream = null;
            inputStream = httpResponse.getEntity().getContent();
            if (inputStream != null)
                result.add(convertInputStreamToString(inputStream));
            else
                result.add("Did not work!");
        }

my new not working code snippt

    try {
        HttpURLConnection httpcon = (HttpURLConnection) ((new URL(imagePostUrl).openConnection()));
        httpcon.setDoOutput(true);
        for (String fileName : fileNameArrayList) {
            File file = new File(fileName);
            int quality = GeneralUtil.getQualityOfImage(file);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            if (quality <= 25) { 
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inJustDecodeBounds = false;
                options.inPreferredConfig = Bitmap.Config.RGB_565;
                options.inDither = true;
                try {
                    bitmap = BitmapFactory.decodeFile(file.getPath(), options);
                } catch (OutOfMemoryError E) {
                    System.gc();
                    bitmap = GeneralUtil.decodeFile(file);

                }
                bitmap.compress(CompressFormat.JPEG, quality, bos);
                bitmap.recycle();
                bitmap = null;

            } else {

                try {
                    bitmap = BitmapFactory.decodeFile(file.getPath());
                    bitmap.compress(CompressFormat.JPEG, quality, bos);
                    bitmap.recycle();
                    bitmap = null;
                } catch (OutOfMemoryError E) {
                    System.gc();

                    try {
                        BitmapFactory.Options options = new BitmapFactory.Options();
                        options.inJustDecodeBounds = false;
                        options.inPreferredConfig = Bitmap.Config.RGB_565;
                        options.inDither = true;

                        bitmap = BitmapFactory.decodeFile(file.getPath(), options);
                        bitmap.compress(CompressFormat.JPEG, quality, bos);
                        bitmap.recycle();
                        bitmap = null;
                    } catch (OutOfMemoryError ex) {

                        bitmap = GeneralUtil.decodeFile(file);
                        bitmap.compress(CompressFormat.JPEG, quality, bos);
                        bitmap.recycle();
                        bitmap = null;
                        throw new Exception();
                    }


                }
            }
            byte[] data = bos.toByteArray();
            String timeStamp = GeneralUtil.generateTimeStamp();
            ByteArrayBody bin = new ByteArrayBody(data, myMobileNo + "_" + userName + "_" + timeStamp + ".jpg");
            MultipartEntityBuilder multiPartEntityBuilder = MultipartEntityBuilder.create();
            multiPartEntityBuilder.addPart("uploadedfile1", bin);
            multiPartEntityBuilder.addPart("inviteId", new StringBody(inviteIdArrayList.get(0).toString(), Charset.forName("UTF-8")));
            httpcon.setEntity(multiPartEntityBuilder.build()); **error**
            // Execute POST request to the given URL
           // HttpResponse httpResponse = null;
          //  httpResponse = client.execute(post);
            httpcon.setRequestMethod("POST");
            httpcon.connect();

回答1:

I was able to get my Multipart Form Data upload thing to work after a lot of head scratching and hair pulling. Below class is used for multipart file uploading and it works. NB: This is not a question, merely an answer to the op.

public class WebConnector {
    String boundary = "-------------" + System.currentTimeMillis();
    private static final String LINE_FEED = "\r\n";
    private static final String TWO_HYPHENS = "--";


    private StringBuilder url;
    private String protocol;
    private HashMap<String, String> params;
    private JSONObject postData;
    private List<String> fileList;
    private int count = 0;
    private DataOutputStream dos;

    public WebConnector(StringBuilder url, String protocol,
                        HashMap<String, String> params, JSONObject postData) {
        super();
        this.url = url;
        this.protocol = protocol;
        this.params = params;
        this.postData = postData;
        createServiceUrl();
    }

    public WebConnector(StringBuilder url, String protocol,
                        HashMap<String, String> params, JSONObject postData, List<String> fileList) {
        super();
        this.url = url;
        this.protocol = protocol;
        this.params = params;
        this.postData = postData;
        this.fileList = fileList;
        createServiceUrl();
    }

    public String connectToMULTIPART_POST_service(String postName) {


        System.out.println(">>>>>>>>>url : " + url);

        StringBuilder stringBuilder = new StringBuilder();

        String strResponse = "";
        InputStream inputStream = null;
        HttpURLConnection urlConnection = null;

        try {
            urlConnection = (HttpURLConnection) new URL(url.toString()).openConnection();
            urlConnection.setRequestProperty("Accept", "application/json");
            urlConnection.setRequestProperty("Connection", "close");
            urlConnection.setRequestProperty("User-Agent", "Mozilla/5.0 ( compatible ) ");
            urlConnection.setRequestProperty("Authorization", "Bearer " + Config.getConfigInstance().getAccessToken());
            urlConnection.setRequestProperty("Content-type", "multipart/form-data; boundary=" + boundary);

            urlConnection.setDoOutput(true);
            urlConnection.setDoInput(true);
            urlConnection.setUseCaches(false);
            urlConnection.setChunkedStreamingMode(1024);
            urlConnection.setRequestMethod("POST");
            dos = new DataOutputStream(urlConnection.getOutputStream());

            Iterator<String> keys = postData.keys();
            while (keys.hasNext()) {
                try {
                    String id = String.valueOf(keys.next());
                    addFormField(id, "" + postData.get(id));
                    System.out.println(id + " : " + postData.get(id));
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
            try {
                dos.writeBytes(LINE_FEED);
                dos.flush();
                dos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (fileList != null && fileList.size() > 0 && !fileList.isEmpty()) {
                for (int i = 0; i < fileList.size(); i++) {

                    File file = new File(fileList.get(i));
                    if (file != null) ;
                    addFilePart("photos[" + i + "][image]", file);
                }
            }
            // forming th java.net.URL object

            build();
            urlConnection.connect();
            int statusCode = 0;
            try {
                urlConnection.connect();
                statusCode = urlConnection.getResponseCode();
            } catch (EOFException e1) {
                if (count < 5) {
                    urlConnection.disconnect();
                    count++;
                    String temp = connectToMULTIPART_POST_service(postName);
                    if (temp != null && !temp.equals("")) {
                        return temp;
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            // 200 represents HTTP OK
            if (statusCode == HttpURLConnection.HTTP_OK) {
                inputStream = new BufferedInputStream(urlConnection.getInputStream());
                strResponse = readStream(inputStream);
            } else {
                System.out.println(urlConnection.getResponseMessage());
                inputStream = new BufferedInputStream(urlConnection.getInputStream());
                strResponse = readStream(inputStream);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != inputStream)
                    inputStream.close();
            } catch (IOException e) {
            }
        }
        return strResponse;
    }

    public void addFormField(String fieldName, String value) {
        try {
            dos.writeBytes(TWO_HYPHENS + boundary + LINE_FEED);
            dos.writeBytes("Content-Disposition: form-data; name=\"" + fieldName + "\"" + LINE_FEED + LINE_FEED/*+ value + LINE_FEED*/);
            /*dos.writeBytes("Content-Type: text/plain; charset=UTF-8" + LINE_FEED);*/
            dos.writeBytes(value + LINE_FEED);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public void addFilePart(String fieldName, File uploadFile) {
        try {
            dos.writeBytes(TWO_HYPHENS + boundary + LINE_FEED);
            dos.writeBytes("Content-Disposition: form-data; name=\"" + fieldName + "\";filename=\"" + uploadFile.getName() + "\"" + LINE_FEED);
            dos.writeBytes(LINE_FEED);

            FileInputStream fStream = new FileInputStream(uploadFile);
            int bufferSize = 1024;
            byte[] buffer = new byte[bufferSize];
            int length = -1;

            while ((length = fStream.read(buffer)) != -1) {
                dos.write(buffer, 0, length);
            }
            dos.writeBytes(LINE_FEED);
            dos.writeBytes(TWO_HYPHENS + boundary + TWO_HYPHENS + LINE_FEED);
        /* close streams */
            fStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void addHeaderField(String name, String value) {
        try {
            dos.writeBytes(name + ": " + value + LINE_FEED);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public void build() {
        try {
            dos.writeBytes(LINE_FEED);
            dos.flush();
            dos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static String readStream(InputStream in) {
        StringBuilder sb = new StringBuilder();
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            String nextLine = "";
            while ((nextLine = reader.readLine()) != null) {
                sb.append(nextLine);
            }
        /* Close Stream */
            if (null != in) {
                in.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sb.toString();
    }

    private void createServiceUrl() {
        if (null == params) {
            return;
        }
        final Iterator<Map.Entry<String, String>> it = params.entrySet().iterator();
        boolean isParam = false;
        while (it.hasNext()) {
            final Map.Entry<String, String> mapEnt = (Map.Entry<String, String>) it.next();
            url.append(mapEnt.getKey());
            url.append("=");
            try {
                url.append(URLEncoder.encode(mapEnt.getValue(), "UTF-8"));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            } catch (NullPointerException e) {
                e.printStackTrace();
            }
            url.append(WSConstants.AMPERSAND);
            isParam = true;
        }
        if (isParam) {
            url.deleteCharAt(url.length() - 1);
        }
    }

}


回答2:

Here is my suggested alternative solution:

First of all, you can refer to some of the following libraries: Volley, Retrofit...

If you want to use Volley, you can refer to some following links:

  • Working POST Multipart Request with Volley and without HttpEntity
  • How to send a “multipart/form-data” POST in Android with Volley

My sample code relating to the first link above

MultipartActivity.java:

public class MultipartActivity extends Activity {

    private final Context context = this;
    private final String twoHyphens = "--";
    private final String lineEnd = "\r\n";
    private final String boundary = "apiclient-" + System.currentTimeMillis();
    private final String mimeType = "multipart/form-data;boundary=" + boundary;
    private byte[] multipartBody;

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

        byte[] fileData1 = getFileDataFromDrawable(context, R.drawable.ic_action_android);
        byte[] fileData2 = getFileDataFromDrawable(context, R.drawable.ic_action_book);

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        DataOutputStream dos = new DataOutputStream(bos);
        try {
            // the first file
            buildPart(dos, fileData1, "ic_action_android.png");
            // the second file
            buildPart(dos, fileData2, "ic_action_book.png");
            // send multipart form data necesssary after file data
            dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
            // pass to multipart body
            multipartBody = bos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }

        String url = "http://192.168.1.100/api/postfile";
        MultipartRequest multipartRequest = new MultipartRequest(url, null, mimeType, multipartBody, new Response.Listener<NetworkResponse>() {
            @Override
            public void onResponse(NetworkResponse response) {
                Toast.makeText(context, "Upload successfully!", Toast.LENGTH_SHORT).show();
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(context, "Upload failed!\r\n" + error.toString(), Toast.LENGTH_SHORT).show();
            }
        });

        VolleySingleton.getInstance(context).addToRequestQueue(multipartRequest);
    }

    ...

    private void buildPart(DataOutputStream dataOutputStream, byte[] fileData, String fileName) throws IOException {
        dataOutputStream.writeBytes(twoHyphens + boundary + lineEnd);
        dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\"; filename=\""
                + fileName + "\"" + lineEnd);
        dataOutputStream.writeBytes(lineEnd);

        ByteArrayInputStream fileInputStream = new ByteArrayInputStream(fileData);
        int bytesAvailable = fileInputStream.available();

        int maxBufferSize = 1024 * 1024;
        int bufferSize = Math.min(bytesAvailable, maxBufferSize);
        byte[] buffer = new byte[bufferSize];

        // read file and write it into form...
        int bytesRead = fileInputStream.read(buffer, 0, bufferSize);

        while (bytesRead > 0) {
            dataOutputStream.write(buffer, 0, bufferSize);
            bytesAvailable = fileInputStream.available();
            bufferSize = Math.min(bytesAvailable, maxBufferSize);
            bytesRead = fileInputStream.read(buffer, 0, bufferSize);
        }

        dataOutputStream.writeBytes(lineEnd);
    }

    private byte[] getFileDataFromDrawable(Context context, int id) {
        Drawable drawable = ContextCompat.getDrawable(context, id);
        Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 0, byteArrayOutputStream);
        return byteArrayOutputStream.toByteArray();
    }
}

MultipartRequest.java:

class MultipartRequest extends Request<NetworkResponse> {
    private final Response.Listener<NetworkResponse> mListener;
    private final Response.ErrorListener mErrorListener;
    private final Map<String, String> mHeaders;
    private final String mMimeType;
    private final byte[] mMultipartBody;

    public MultipartRequest(String url, Map<String, String> headers, String mimeType, byte[] multipartBody, Response.Listener<NetworkResponse> listener, Response.ErrorListener errorListener) {
        super(Method.POST, url, errorListener);
        this.mListener = listener;
        this.mErrorListener = errorListener;
        this.mHeaders = headers;
        this.mMimeType = mimeType;
        this.mMultipartBody = multipartBody;
    }

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

    @Override
    public String getBodyContentType() {
        return mMimeType;
    }

    @Override
    public byte[] getBody() throws AuthFailureError {
        return mMultipartBody;
    }

    @Override
    protected Response<NetworkResponse> parseNetworkResponse(NetworkResponse response) {
        try {
            return Response.success(
                    response,
                    HttpHeaderParser.parseCacheHeaders(response));
        } catch (Exception e) {
            return Response.error(new ParseError(e));
        }
    }

    @Override
    protected void deliverResponse(NetworkResponse response) {
        mListener.onResponse(response);
    }

    @Override
    public void deliverError(VolleyError error) {
        mErrorListener.onErrorResponse(error);
    }
}

Of course, you can find more available in SO.

Hope this helps!