Post files to server from Android - MultipartEntit

2019-02-28 15:36发布

问题:

I am trying to upload some files to my server (via HTTP POST) from an Android app and I have checked many Questions here but can't get it to work. I hope someone can help me out:

I also included some variables in the URL to verify that at least those are reaching the server(GET).

    HttpClient httpClient = new DefaultHttpClient();
    String url="http://XXXXX.com/files/upload.php?flies=yes&eats=no&friend=yes";
    HttpPost httppost = new HttpPost(url);
    httppost.addHeader("Content-Type", "multipart/form-data");
    String content,response="";
    try {

        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
        builder.addTextBody("randomvar", "42");

        //add image file
        //String filename="eye.png";
        //InputStream is=mContext.getAssets().open(filename);
        //builder.addBinaryBody("image", is, ContentType.create("image/png"), filename);

        //add text XML file
        final File file = new File(mContext.getFilesDir() +"/"+"serverXML.xml");
        FileBody fb = new FileBody(file);
        builder.addPart("file", fb);
        httppost.setEntity(builder.build());


        response = EntityUtils.toString(httpClient.execute(httppost).getEntity(), "UTF-8");


        Log.i(TAG, "RESPONSE FROM SERVER: "+response);
    } catch (IOException e) {
        Log.i(TAG, "Exception: "+response);
        e.printStackTrace();
    }

This does run and get a response from the server. The following is the vardump of $_GET, $_POST, $_FILES:

I would want POST to have the file and variable

In my Eclipse Logcat I see the following after using MultiPartEntityBuilder:

10-06 02:36:57.231: D/dalvikvm(15888): DexOpt: couldn't find static field Lorg/apache/http/message/BasicHeaderValueParser;.INSTANCE
10-06 02:36:57.241: W/dalvikvm(15888): VFY: unable to resolve static field 5966 (INSTANCE) in Lorg/apache/http/message/BasicHeaderValueParser;
10-06 02:36:57.241: D/dalvikvm(15888): VFY: replacing opcode 0x62 at 0x001b
10-06 02:36:57.241: D/dalvikvm(15888): DexOpt: couldn't find static field Lorg/apache/http/message/BasicHeaderValueFormatter;.INSTANCE
10-06 02:36:57.241: W/dalvikvm(15888): VFY: unable to resolve static field 5960 (INSTANCE) in Lorg/apache/http/message/BasicHeaderValueFormatter;

I think I have correctly included all the required libraries:

EDIT:

I was able to solve this, my solution is the described in my answer below

回答1:

I was fortunate enough to find one Answer by Krystian in Stackoverflow that solved my issue.

After adding the boundary it started working. I had to add it to the HTTP Post

String boundary = "-------------" + System.currentTimeMillis();
httppost.setHeader("Content-type", "multipart/form-data; boundary="+boundary);

and to the entity

MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.setBoundary(boundary);

Now I get everything in the server:

10-06 13:16:06.977: I/UploadFileAsync(31506): RESPONSE FROM SERVER: Array
10-06 13:16:06.977: I/UploadFileAsync(31506): (
10-06 13:16:06.977: I/UploadFileAsync(31506):     [flies] => yes
10-06 13:16:06.977: I/UploadFileAsync(31506):     [eats] => no
10-06 13:16:06.977: I/UploadFileAsync(31506):     [friend] => yes
10-06 13:16:06.977: I/UploadFileAsync(31506): )
10-06 13:16:06.977: I/UploadFileAsync(31506): Array
10-06 13:16:06.977: I/UploadFileAsync(31506): (
10-06 13:16:06.977: I/UploadFileAsync(31506):     [randomvar] => 42
10-06 13:16:06.977: I/UploadFileAsync(31506):     [mystr] => blaka
10-06 13:16:06.977: I/UploadFileAsync(31506): )
10-06 13:16:06.977: I/UploadFileAsync(31506): Array
10-06 13:16:06.977: I/UploadFileAsync(31506): (
10-06 13:16:06.977: I/UploadFileAsync(31506):     [file] => Array
10-06 13:16:06.977: I/UploadFileAsync(31506):         (
10-06 13:16:06.977: I/UploadFileAsync(31506):             [name] => serverXML.xml
10-06 13:16:06.977: I/UploadFileAsync(31506):             [type] => application/octet-stream
10-06 13:16:06.977: I/UploadFileAsync(31506):             [tmp_name] => /tmp/phpdmEsn2
10-06 13:16:06.977: I/UploadFileAsync(31506):             [error] => 0
10-06 13:16:06.977: I/UploadFileAsync(31506):             [size] => 3548
10-06 13:16:06.977: I/UploadFileAsync(31506):         )
10-06 13:16:06.977: I/UploadFileAsync(31506): )


回答2:

You have to work like this

public void connectForMultipart() throws Exception {
    con = (HttpURLConnection) ( new URL(url)).openConnection();
    con.setRequestMethod("POST");
    con.setDoInput(true);
    con.setDoOutput(true);
    con.setRequestProperty("Connection", "Keep-Alive");
    con.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
    con.connect();
    os = con.getOutputStream();
}

public void addFormPart(String paramName, String value) throws Exception {
    writeParamData(paramName, value);
}

public void addFilePart(String paramName, String fileName, byte[] data) throws Exception {
    os.write( (delimiter + boundary + "\r\n").getBytes());
    os.write( ("Content-Disposition: form-data; name=\"" + paramName +  "\"; filename=\"" + fileName + "\"\r\n"  ).getBytes());
    os.write( ("Content-Type: application/octet-stream\r\n"  ).getBytes());
    os.write( ("Content-Transfer-Encoding: binary\r\n"  ).getBytes());
    os.write("\r\n".getBytes());

    os.write(data);

    os.write("\r\n".getBytes());
}   
public void finishMultipart() throws Exception {
    os.write( (delimiter + boundary + delimiter + "\r\n").getBytes());
}

for getting response

httpPost.setEntity(entity);
HttpResponse response = httpClient.execute(httpPost);

BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));



String sResponse;
while ((sResponse = reader.readLine()) != null) 
 {
     s = s.append(sResponse);
 }

 if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK)
 {
     return s.toString();
 }else
 {
     return "{\"status\":\"false\",\"message\":\"Some error occurred\"}";
 }   
} catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

In place of image you can send anything(in your case its xml file), you would like to... if it creates some heck then you should divide the large file into small parts then try to sending.And Join this small part on the server.

In my case httpmime-4.2.1-1.jar is only needed in this code