Uploading file via form into GAE from Android

2019-07-24 12:31发布

I have an app on GAE at: http://1.myawesomecity.appspot.com/

FIXED:

                HttpPost post = new HttpPost("http://1.myawesomecity.appspot.com/");
                http_client.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
                String result = EntityUtils.toString( http_client.execute(post).getEntity(), "UTF-8");
                String actualURL = result.substring(result.indexOf("http://"), result.indexOf("\" method"));
                Log.w("asdf", "url " + actualURL );


                post = new HttpPost(actualURL);
                http_client.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);                    
                MultipartEntity entity = new MultipartEntity( HttpMultipartMode.BROWSER_COMPATIBLE );
                String mime_type = "image/png";
                File file = new File( filename ); //context.getFilesDir(), 
                entity.addPart( "myFile", new FileBody( file, mime_type));
                post.setEntity( entity );

                String res = EntityUtils.toString( http_client.execute(post).getEntity(), "UTF-8");
                Log.w("asdf", res);

The above grabs the ACTUAL upload URL from the GAE server, and passes in the file as dictated by the CORRECT answer below.

Old Question:

As you can see, if you choose a file and hit submit, it will 404, but the file actually does get stored (as long as it is not too big, < 100kb). Don't type in anything in the first text field.

Now, putting aside how this particular app is barely functional, I'm trying to upload a file from Android onto this server.

The site's upload script uses blobstore, and the file field's name is "myFile".

Now in my Android app, I have:

    HttpClient httpclient = new DefaultHttpClient();

    HttpPost httppost = new HttpPost(<my app's url>);

    List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
    nameValuePairs.add(new BasicNameValuePair("myFile", <path to a file selected by user> ) );
    httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

    httpclient.execute(httppost);

This throws an exception.

How is this any different from me going to my site through a browser, choosing a file, and hitting submit? Why does going through a browser actually go through with uploading the file, when the Android code does not?

I know that my filepath is valid. Is there something I'm doing wrong? or is clicking on "submit" from a browser different from executing a httpclient from Android?

1条回答
兄弟一词,经得起流年.
2楼-- · 2019-07-24 12:46

Uploading file to a blobstore on GAE is a two step process:

  1. first you need to get a proper URL where to POST your data, usually people use something like "/bloburl" handler for that purpose

  2. when you have blob upload URL, you use it in your request.

  3. the file you send does not go as NameValuePair, it's supposed to go as a MultiPartEntity.

here's the code that works (you'll need apache http library for MultiPartEntry support):

DefaultHttpClient http_client = new DefaultHttpClient();
HttpGet http_get = new HttpGet(Config.BASE_URL + "bloburl");
HttpResponse response = http_client.execute(http_get);
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String first_line = reader.readLine();
Log.w(TAG, "blob_url: " + first_line);

HttpPost post = new HttpPost(first_line);
http_client.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
MultipartEntity entity = new MultipartEntity( HttpMultipartMode.BROWSER_COMPATIBLE );

mime_type = "application/zip";
File file = new File( context.getFilesDir(), filename );
entity.addPart( "file", new FileBody( file, mime_type));
post.setEntity( entity );

String result = EntityUtils.toString( http_client.execute(post).getEntity(), "UTF-8");
Log.i(TAG, result);
查看更多
登录 后发表回答