Skip to content

MultiPartPost #154

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
rfmussa opened this issue Dec 13, 2012 · 18 comments
Closed

MultiPartPost #154

rfmussa opened this issue Dec 13, 2012 · 18 comments
Assignees
Milestone

Comments

@rfmussa
Copy link

rfmussa commented Dec 13, 2012

Can you give me an example on how to perform MultipartPost using this library? iam trying to post a photo + text, and dont know how to make the requestparams(what/how should i use inputstream)

@bywyu
Copy link

bywyu commented Dec 27, 2012

Add a File object to the RequestParams to upload:

File myFile = new File("/path/to/file.png");
RequestParams params = new RequestParams();
try {
params.put("profile_picture", myFile);
} catch(FileNotFoundException e) {}

@zondaOf2012
Copy link

ee呃呃刚才

@bkhall
Copy link
Contributor

bkhall commented Jan 25, 2013

This works fine for small files.

However, because the RequestParams class creates a non-buffered ByteArrayEntity to pass to the POST or PUT call, it is very easy to cause OutOfMemory errors with larger files, like when uploading a video or mp3 to a server, which are often larger than 4 or 5 MB.

A better solution is to use the MultipartEntity in the apache mime library and pass that to the POST or PUT call. That entity is buffered and I have used it often to upload >> 100MB files.

@bangandi
Copy link

@bkhall I try to upload a large image and failed. At the end i ended up here. I try to use method you mentioned above with apache mime, but how do I pass MultipartEntity in the POST call? Do you have any example?

So far this is what i've got :
MultipartEntity multipartEntity = new MultipartEntity();
multipartEntity.addPart("id", new StringBody(String.valueOf(id)));
multipartEntity.addPart("userfile", new FileBody(file));
multipartEntity.addPart("submit", new StringBody("upload"));

Thanks in advance.

@2fours
Copy link

2fours commented Apr 19, 2013

@bangandi try something similar to this:

...
HttpPost httppost = new HttpPost(url);

InputStreamBody isBody = new InputStreamBody(inputStream, mimeType, filename);

MultipartEntity reqEntity = new MultipartEntity();
reqEntity.addPart("part", isBody);
httpPost.setEntity(reqEntity);

HttpResponse = client.execute(httppost);

@bangandi
Copy link

@2fours cmiiw, your code doesn't use loopj at all?

@bkhall
Copy link
Contributor

bkhall commented Apr 19, 2013

@bangandi

There are a number of ways to use the MultipartEntity for uploading a file. By far, the most common is something like this.

File file = new File([path to your file]);

MimeTypeMap map = MimeTypeMap.getSingleton();
String ext = FilenameUtils.getExtension(file.getName());
String mime_type = map.getMimeTypeFromExtension(ext);

String userAgent = System.getProperty("http.agent", "Android device");
AndroidHttpClient httpClient = AndroidHttpClient.newInstance(userAgent);

HttpPost httpPost = new HttpPost([your url here]);

MultipartEntity form = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE, this);
form.addPart("file-data", new FileBody(file, mime_type, "UTF-8"));

httpPost.setEntity(form);

HttpResponse httpResponse = httpClient.execute(httpPost);

httpClient.close();

That's a basic example. You should wrap it with appropriate try-catch blocks, etc.

If you want to use the MultipartEntity with the android-async-http project just pass the object to an AsyncHttpClient like this:

File file = new File([path to your file]);

MimeTypeMap map = MimeTypeMap.getSingleton();
String ext = FilenameUtils.getExtension(file.getName());
String mime_type = map.getMimeTypeFromExtension(ext);

MultipartEntity form = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE, this);
form.addPart("file-data", new FileBody(file, mime_type, "UTF-8"));

AsyncHttpClient client = new AsyncHttpClient();
client.post(context, [your url], form, mime_type, responseHandler) ;

Again, just a basic example. Follow the android-async-http project documentation and recommendations for creating the client and response handlers.

@2fours
Copy link

2fours commented Apr 19, 2013

Not in that code snippet but you should be able to call one of the post overloads in loopj client that accepts the entity.

@bangandi
Copy link

@bkhall this is what i do so far. Its not getting any response, it's starting, but onFinished & onFailure & onSuccess not getting any call. when i try to debug the mime, it give the correct result (image/jpeg). Am i missing something?

public void uploadImage(Uri uri, int id, Context ctx) {
    File file = new File(uri.getPath());
    ContentResolver cR = ctx.getContentResolver();
    String mime = cR.getType(uri);      

    MultipartEntity multipartEntity = new MultipartEntity();
    try {
        multipartEntity.addPart("id", new StringBody(String.valueOf(id)));
        multipartEntity.addPart("tag", new StringBody(Constants.EVENT_UPLOAD_IMAGE));
        multipartEntity.addPart("userfile", new FileBody(file));
        multipartEntity.addPart("submit", new StringBody("upload"));
    } catch (UnsupportedEncodingException e) {          
        e.printStackTrace();
    }

    RestClient.post(ctx, RestClient.URL_UPLOAD_IMAGE, multipartEntity,
            mime, new AsyncHttpResponseHandler() {

    //I overide onSuccess, onFailure, onStart, onFinish here, but only onStart fired

    });
}

@Kozlov-V
Copy link

Sorry,
I test you code, this not uploading over 1MB

@bkhall
Copy link
Contributor

bkhall commented Jul 29, 2013

@Kozlov-V There are several code snippets in here. To whose are you referring? If to mine, then something else is wrong, because I use this pattern in many published apps with the async library. No one is intentionally misleading...but the code snippets in here are also not exhaustive.

What kind of error are you getting? Is the server configured to allow uploads larger than 1MB? There are at least 3 server side settings that can affect upload size limits.

@Kozlov-V
Copy link

@bkhall Sorry! i non test you code. Tomorrow i will do it, but I think I understand what my mistake (: and tell the details

@wuyexiong
Copy link

我是这样解决的,上传大文件的问题。改写了RequestParams.java这个类

/**
     * Returns an HttpEntity containing all request parameters
     */
    public HttpEntity getEntity() {
        HttpEntity entity = null;

        if(!fileParams.isEmpty()) {
            MultipartEntity multipartEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE, null, MIME.DEFAULT_CHARSET);
            // Add string params
            for(ConcurrentHashMap.Entry<String, String> entry : urlParams.entrySet()) {
                try
                {
                    multipartEntity.addPart(entry.getKey(), new StringBody(entry.getValue()));
                } catch (UnsupportedEncodingException e){}
            }

            for(ConcurrentHashMap.Entry<String, FileWrapper> entry :fileParams.entrySet())
            {
                FileWrapper file = entry.getValue();
                multipartEntity.addPart(entry.getKey(), new FileBody(file.mFile, file.contentType));
            }
            entity = multipartEntity;
        } else {
            try {
                entity = new UrlEncodedFormEntity(getParamsList(), ENCODING);
            } catch (UnsupportedEncodingException e) {
                Log.e("", "UrlEncodedFormEntity error : " + e.toString());
            }
        }

        return entity;
    }
public void put(String key, File file, String contentType)
    {
        if(!TextUtils.isEmpty(key) && file != null)
        {
            fileParams.put(key, new FileWrapper(file, contentType));
        }
    }

@Kozlov-V
Copy link

@bkhall Respected Baron!
I test this code:

There are a number of ways to use the MultipartEntity for uploading a file. By far, the most common is something like this.

File file = new File([path to your file]);
MimeTypeMap map = MimeTypeMap.getSingleton();
String ext = FilenameUtils.getExtension(mStorageItem.getName());
String mime_type = map.getMimeTypeFromExtension(ext);
String userAgent = System.getProperty("http.agent", "Android device");
AndroidHttpClient httpClient = AndroidHttpClient.newInstance(userAgent);
HttpPost httpPost = new HttpPost([your url here]);
MultipartEntity form = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE, this);
form.addPart("file-data", new FileBody(file, mime_type, "UTF-8"));
httpPost.setEntity(form);
HttpResponse httpResponse = httpClient.execute(httpPost);
httpClient.close();

and my http server close socket by timeout, when i post file over 1MB (my http server have keepalive timeout 5000)

@wuyexiong

I need to to understand and the test it

@bkhall
Copy link
Contributor

bkhall commented Jul 30, 2013

@2fours The last line of my example does exactly that.

@wuyexiong Your sample works also, but requires extending the class and overriding the method.

@Kozlov-V Server side settings are outside the scope of this thread. I may be able to help you though. Just send me a private message.

@wuyexiong
Copy link

@bkhall thank you

In order to upload large files, so to do so

@Kozlov-V
Copy link

Kozlov-V commented Aug 1, 2013

Thank you!
I realized!!! My Android Client send file on server very slow-slow, and need more timeout, but also for local network ( 7MB filesize = 90 s)
on my http server i m set timeout 100000 and its work!
90 s - its badly (

@smarek
Copy link
Member

smarek commented Oct 12, 2013

Ok, so this thread obviously has solution. Use proper timeout if needed.
@wuyexiong I see your snippet, could you propose a merge request based on it?
I'm closing this thread, as the origin issue is cleared out.

@smarek smarek closed this as completed Oct 12, 2013
@ghost ghost assigned smarek Oct 14, 2013
iNdieboyjeff pushed a commit to iNdieboyjeff/android-async-http that referenced this issue Oct 15, 2013
# By mareksebera (7) and Ankush Sachdeva (1)
# Via Ankush Sachdeva (1) and Marek Sebera (1)
* 'master' of https://github.com/loopj/android-async-http:
  Added Proxy Authentication ; fixes android-async-http#328
  Fixed wrong static field, Closing android-async-http#229
  Manual merge, Closing android-async-http#269, android-async-http#118, Closing android-async-http#10, Closing android-async-http#127, android-async-http#154
  Closes android-async-http#137
  Removing duplicate call
  Closing android-async-http#179
  Updated Gradle Android tools version
  Cleaning up error message output
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants