我正在尝试将Android应用内的POST请求发送到我的Google App Engine应用,以便将文件上传到blobstore,并将一些元数据上传到数据存储区。我构建了一个常规的webform,我可以从浏览器访问,从那里发布工作就好了。但是,我的Android应用程序无法做到这一点。
许多其他StackOverflow帖子提到使用MultipartEntity
或MultipartEntityBuilder
来构建帖子请求。前者似乎已被弃用,但有更多的例子,所以我尝试了两种方式(当然是单独的):
HttpClient httpClient = new DefaultHttpClient();
HttpPost postRequest = new HttpPost(upload_url);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.addTextBody("poem_name", "Testing poem_name from Android", ContentType.MULTIPART_FORM_DATA);
builder.addTextBody("poem_text", "blah", ContentType.MULTIPART_FORM_DATA);
postRequest.setEntity(builder.build());
HttpResponse response = httpClient.execute(postRequest);
HttpEntity theEntity = response.getEntity();
theEntity.consumeContent();
httpClient.getConnectionManager().shutdown();
和
HttpClient httpClient = new DefaultHttpClient();
HttpPost postRequest = new HttpPost(upload_url);
StringBody poem_name = new StringBody("Testing poem_name from Android");
StringBody poem_text = new StringBody("blah");
MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
entity.addPart("poem_name", poem_name);
entity.addPart("poem_text", poem_text);
postRequest.setEntity(entity);
HttpResponse response = httpClient.execute(postRequest);
原始的webform,就像常规浏览器中的一个魅力一样,在我的模板中看起来像这样(我最初在Android代码中省略了文件上传,因为这对于立即调试来说太麻烦了):
<form action="{{ upload_url }}" method="POST" enctype="multipart/form-data">
Poem Title: <input name="poem_name" required><br>
Poem Text:<br><textarea name="poem_text" rows="5" cols="40"></textarea><br>
Upload File: <input type="file" name="file"><br>
<input type="submit" name="submit" value="Add Poem">
</form>
然而,当我在Android应用程序上执行前两部分代码中的任何一部分时,我的服务器上都没有显示任何内容。传递给HttpPost构造函数的upload_url与Web表单{{ upload_url }}
的操作字段中使用的一样(它由Google App Engine动态生成)。所以,我想我会尝试发布到任何Web表单,而不是需要多部分实体和动态URL的表单。我在应用程序的不同页面上构建了一个新的准系统Web表单,就像这样......
<form action="/testForm" method="post">
<input name="nickname"><br>
<input type="submit" value="Create Test Entity">
</form>
...并尝试了一个基本的帖子请求,如许多初学者的例子所示:
HttpClient httpClient = new DefaultHttpClient();
HttpPost postRequest = new HttpPost("http://my-app-title.appspot.com/testForm");
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
nameValuePairs.add(new BasicNameValuePair("nickname", "test with NameValuePair"));
postRequest.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpClient.execute(postRequest);
果然,这个表单在浏览器中效果很好但是从我的Android应用程序执行此代码时没有产生任何结果(甚至没有代替“昵称”字段的空值,这告诉我问题在于发布请求因某种原因没有被执行)。根据我所读过的所有说法,这应该有效。有什么我忘了哪些不允许我完成发布请求?我真的很感激任何帮助。
答案 0 :(得分:1)
根据njzk2的建议,我使用InputStream来查看HttpResponse的内容。作为参考,这是我使用的代码:
InputStream iStream = response.getEntity().getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(iStream));
while ((tempString = reader.readLine()) != null) {
postResponseOutput += tempString;
}
Log.d("HttpResponse Output", postResponseOutput);
对于准系统表单,我错误地要求在/ testForm上登录网址,因此返回了Google的登录页面,而不是我的表单。删除该限制使表单完美运行。
尝试使用我的代码的MultipartEntityBuilder
部分在帖子回复中返回了一些有趣的内容,仅仅是&#34;此网址上不接受请求的内容类型&#34;。但尝试使用MultipartEntity
部分似乎可以解决问题。 httpresponse返回了内部服务器错误(与用户身份验证有关)。这就解释了为什么发布到原始webform并不起作用 - 存在服务器错误,导致首先无法访问表单。我相信,一旦我解决了错误,表单就会像我的testForm一样工作。