【问题标题】:Using InputStream with MultipartEntityBuilder : apache error将 InputStream 与 MultipartEntityBuilder 一起使用:apache 错误
【发布时间】:2013-12-31 22:12:26
【问题描述】:

我正在使用 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 中运行)。 我正在尝试发送本地文件,结果我从网络服务器收到错误,这是来自网络服务器的日志:

[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。 [2013 年 12 月 13 日星期五 15:01:03] [错误] 错误:django.request:内部服务器错误:/api/content/add/image/ [2013 年 12 月 13 日星期五 15:01:03] [错误] 回溯(最后一次通话): [2013 年 12 月 13 日星期五 15:01:03] [错误] 文件“/var/www/ezduki/venv/lib/python2.6/site-packages . . . packages/django/core/handlers/wsgi.py”,第 92 行,在 _read_limited [2013 年 12 月 13 日星期五 15:01:03] [错误] 结果 = self.stream.read(size) [Fri Dec 13 15:01:03 2013] [error] IOError:请求数据读取错误 [2013 年 12 月 13 日星期五 15:01:03] [错误] [客户端 93.157.241.232] mod_wsgi (pid=28709):处理 WSGI 脚本“/var/www/ezduki/app/wsgi.py”时发生异常。 [Fri Dec 13 15:01:03 2013] [error] [client 93.157.241.232] IOError: failed to write data

我必须如何同时使用 MultipartEntityBuilder 和 InputStream?像这样发送文件

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

完美运行

【问题讨论】:

    标签: android http inputstream


    【解决方案1】:

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

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

    【讨论】:

    • 你“认为”一个可以使用?你自己试过吗?
    • 我已经成功使用过类似的:.addPart("file", new ByteArrayBody(byteFile,"filename.JPG"))
    【解决方案2】:

    如果你通过流发送文件,你只能通过服务器上的Request的InputStream获取文件,我使用的是dot net服务器,你可以参考我的代码。

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

    【讨论】:

      【解决方案3】:

      没有找到直接的解决方案。这样做知道:

              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】:

        您是否尝试过使用 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 是位图,我以字节为单位进行转换,然后尝试将多部分发送到服务器

        【讨论】:

          【解决方案5】:

          我遇到了同样的问题,将 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),您解决了这个问题吗?

          【讨论】:

            【解决方案6】:

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

            这里是实现

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

            【讨论】:

            • 正如我所说,发送文件非常完美。我对使用流感兴趣,因为用户可以在画廊中选择不是本地图像 - 并且没有真正的文件路径,它在谷歌的某个地方。顺便说一句,不推荐使用 MultipartEntity。使用 MultipartEntityBuilder
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2014-08-11
            • 2013-01-07
            • 2014-07-13
            • 1970-01-01
            • 1970-01-01
            • 2012-10-04
            • 2011-09-12
            相关资源
            最近更新 更多