вторник, 17 декабря 2013 г.

Using InputStream with MultipartEntityBuilder

Hello all!
Few days ago i had a simple task: send image file to web server. I found apache lib with MultipartEntityBuilder class - it seems to be popular among coders.
It has method that seems to allow using InputStream. But it does not work!

Here is the code that DOES NOT work, and I don't know why:


   
HttpClient httpclient = new DefaultHttpClient();
JSONObject result;
HttpPost httppost = new HttpPost("http://www.ezduki.ru/api/content/add/image/");
InputStream iStream = con.getContentResolver().openInputStream(imageUri);
MultipartEntityBuilder multipartEntity = MultipartEntityBuilder.create();
multipartEntity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
multipartEntity.addTextBody("token", code);
multipartEntity.addBinaryBody("file", iStream);
httppost.setEntity(multipartEntity.build());
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
result = new JSONObject(EntityUtils.toString(entity));
 
I did not find the way to make it work with InputStream correctly: 
web server gives an error, POST message is wrong. So I did it my way:

 
   
        MultipartEntityBuilder multipartEntity = MultipartEntityBuilder.create();
        multipartEntity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
        multipartEntity.addTextBody("token", code);

        InputStream iStream = con.getContentResolver().openInputStream(imageUri);
        // saving temporary file
        String filePath = saveStreamTemp(iStream);
        File f = new File(filePath);
        multipartEntity.addPart("file", new FileBody(f));
        httppost.setEntity(multipartEntity.build());
        HttpResponse response = httpclient.execute(httppost);
        HttpEntity entity = response.getEntity();
        result = new JSONObject(EntityUtils.toString(entity));
        f.delete();

    String saveStreamTemp(InputStream fStream){
    final File file;
    try {
        String timeStamp =
                new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());

        file = new File(con.getCacheDir(), "temp_"+timeStamp + ".jpg");
        final OutputStream output;
        try {
            output = new FileOutputStream(file);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return "";
        }
        try {
            try {
                final byte[] buffer = new byte[1024];
                int read;

                while ((read = fStream.read(buffer)) != -1)
                    output.write(buffer, 0, read);

                output.flush();
            } finally {
                output.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    } finally {
        try {
            fStream.close();
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
    }

    return file.getPath();
}