将InputStream与MultipartEntityBuilder一起使用:apache错误

时间:2013-12-13 07:44:29

标签: android http inputstream

我正在使用MultipartEntityBuilder,我想在服务器上发送图像。我有图像Uri。图像可能是本地的,也可能不是,所以我得到输入流并以这种方式发送:

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

其中con是我的主要活动上下文(代码在AsyncTask中运行)。 我正在尝试发送本地文件,我在结果中从Web服务器收到错误,这里是来自Web服务器的日志:

[Fri Dec 13 10:01:03 2013] [error] [client 93.157.241.232](70014)找到的文件结尾:mod_wsgi(pid = 28449):无法获取请求的桶旅。 [Fri Dec 13 15:01:03 2013] [错误]错误:django.request:内部服务器错误:/ api / content / add / image / [Fri Dec 13 15:01:03 2013] [错误]回溯(最近的呼叫最后): [Fri Dec 13 15:01:03 2013] [错误]文件“/var/www/ezduki/venv/lib/python2.6/site-packages 。 。 。 package / django / core / handlers / wsgi.py“,第92行,在_read_limited中 [Fri Dec 13 15:01:03 2013] [error] result = self.stream.read(size) [Fri Dec 13 15:01:03 2013] [错误] IOError:请求数据读取错误 [Fri Dec 13 15:01:03 2013] [错误] [client 93.157.241.232] mod_wsgi(pid = 28709):处理WSGI脚本'/var/www/ezduki/app/wsgi.py'时发生异常。 [Fri Dec 13 15:01:03 2013] [错误] [client 93.157.241.232] IOError:无法写入数据

我如何一起使用MultipartEntityBuilder和InputStream?像这样发送文件

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

完美运作

6 个答案:

答案 0 :(得分:2)

也许你已经发现了。 但我认为你可以使用:

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

答案 1 :(得分:1)

如果你按流发送文件,你只能通过服务器上的InputStream获取文件,我使用点网服务器,你可以引用我的代码。

1,客户端方式

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

服务器接收

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

2,你想要按流式传输

客户

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

接收服务器

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

答案 2 :(得分:0)

未找到直接解决方案。这样做就知道了:

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

答案 3 :(得分:0)

你尝试使用MultiparEntity吗?请参阅此代码并尝试

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

如下所示,attachImage是一个位图,我在Bytes中转换然后我尝试将多部分发送到服务器

答案 4 :(得分:0)

我遇到了同样的问题,将 InputStream 与 MultipartEntityBuilder 一起使用;请求体中出现莫名其妙的字符(eg:109d),导致文件上传失败:

POST /gcsa/web/personnel/pictureUpload.do HTTP/1.1
Transfer-Encoding: chunked
Content-Type: multipart/form-data; 
boundary=2ZYKoujgt0ExmEBwwwEOeB5cTXqjIiMKFrsr; charset=UTF-8
Host: 10.196.75.219:8664
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.5.13 (Java/1.8.0_181)
Expect: 100-continue
Accept-Encoding: gzip,deflate

HTTP/1.1 100 Continue
Content-Length: 0

109d
--2ZYKoujgt0ExmEBwwwEOeB5cTXqjIiMKFrsr
Content-Disposition: form-data; name="imageFile"; filename="wucheng1.jpg"
Content-Type: application/octet-stream

使用文件时上面没有多余的字符(例如:109d),你解决这个问题了吗?

答案 5 :(得分:-1)

在使用文本单独发送图像时,我们应该提到文件类型..

这是实现

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