可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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);