Using InputStream with MultipartEntityBuilder : ap

2019-04-16 13:20发布

问题:

I am using MultipartEntityBuilder and i want to send image on server. I have image Uri. Image may be local or not, so i get input stream and send it this way:

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));

where con is my main activity context (code runs in AsyncTask). I am trying to send local file, and i get error from web server in result, here is log from web server:

[Fri Dec 13 10:01:03 2013] [error] [client 93.157.241.232] (70014)End of file found: mod_wsgi (pid=28449): Unable to get bucket brigade for request. [Fri Dec 13 15:01:03 2013] [error] ERROR:django.request:Internal Server Error: /api/content/add/image/ [Fri Dec 13 15:01:03 2013] [error] Traceback (most recent call last): [Fri Dec 13 15:01:03 2013] [error] File "/var/www/ezduki/venv/lib/python2.6/site-packages . . . packages/django/core/handlers/wsgi.py", line 92, in _read_limited [Fri Dec 13 15:01:03 2013] [error] result = self.stream.read(size) [Fri Dec 13 15:01:03 2013] [error] IOError: request data read error [Fri Dec 13 15:01:03 2013] [error] [client 93.157.241.232] mod_wsgi (pid=28709): Exception occurred processing WSGI script '/var/www/ezduki/app/wsgi.py'. [Fri Dec 13 15:01:03 2013] [error] [client 93.157.241.232] IOError: failed to write data

How must i use MultipartEntityBuilder and InputStream together? Sending file like this

File f = new File(filePath);
multipartEntity.addPart("file", new FileBody(f));

works perfectly

回答1:

maybe you have already found out. But I think you can use:

InputStream inputStream = ... ;
multipartEntity.addPart("file", new InputStreamBody(inputStream,"testFile.txt"))


回答2:

if you send the file by stream,you just only can get the file by InputStream of Request on server,i'm use the dot net server,you can reference my code.

1,the client way

 for (File file : files) {
            multipartEntityBuilder.addBinaryBody(file.getName(), file);
//            multipartEntityBuilder.addBinaryBody("file_a",file,ContentType.create("image/jpeg"),file.getName());
//            multipartEntityBuilder.addPart("jpg",new FileBody(file));
        }

server receive

 foreach (var key in files.AllKeys)
            {
                HttpPostedFileBase hpf = files.Get(key);
.....
}

2,you want way by stream

the client

 String boundary = creatBoundary();
        multipartEntityBuilder.addBinaryBody("no_name_file", is).setBoundary(boundary);
  HttpEntity he = multipartEntityBuilder.build();
        HttpPostHC4 httpPostHC4 = new HttpPostHC4(url);
        httpPostHC4.setEntity(he);
  httpPostHC4.setHeader("Content-type", "multipart/form-data; boundary="+boundary);
        httpPostHC4.setHeader("IsStream","true");

receive server

     if (Request.Headers.AllKeys.Any((key)=>key=="IsStream"))
                {
                    if(Request.Headers.Get("IsStream")=="true")
                    {
                        Models.File mf = new Models.File();
                        mf.Name = Request.Form.Get("file_name");
                        mf.Size = (int)Request.InputStream.Length;
                        if (Request.InputStream.CanRead)
                        {
                            string guid = Guid.NewGuid().ToString();
                            string p = Path.Combine(Request.MapPath("UploadFiles"), Path.GetFileName(guid));
                            using(FileStream fs = new FileStream(p,FileMode.Create))
                            {
                                Request.InputStream.CopyTo(fs);
                            }
                           }
                          }
                 }


回答3:

Did not find direct solution. Do it this way know:

        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();
}


回答4:

Did you try with MultiparEntity? See this code and try

             ByteArrayOutputStream stream = new ByteArrayOutputStream();
             attachImage.compress(Bitmap.CompressFormat.PNG, 40, stream);
             byte[] imageData = stream.toByteArray();

             MultipartEntityBuilder builder = MultipartEntityBuilder.create();

             builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);

             builder.addBinaryBody(bitmapNameParam, imageData, ContentType.create("image/png"), "photo.png");

             builder.addPart("oauth_token",  new StringBody("Your param", ContentType.APPLICATION_JSON));

As you see below, attachImage is a bitmap and I transform in Bytes then i try to send a multipart to the server



回答5:

While sending images alone with text ,we should mention the file type..

Here is implementation

HttpClient htpclnt = new DefaultHttpClient();

            HttpPost hpost = new HttpPost(URL);

            try {

                MultipartEntity entity = new MultipartEntity(
                        HttpMultipartMode.BROWSER_COMPATIBLE);


                File imagefile = new File(SDcard full path);


                entity.addPart("caption", new StringBody("My image"));

                entity.addPart("image", new FileBody(imagefile ));


                hpost.setEntity(entity);

                HttpResponse response = htpclnt.execute(hpost);