使用来自 Android 应用程序的文件和文本发出 POST 请求
Make a POST request with file and text from an Android application
我在从我的 Android 应用程序向我的 Web 服务(Google 云和 PHP)发出正确的 POST 请求时遇到一些问题。
当我尝试从 Android 发送图像时,它 returns 收到“200 OK”响应,但图像未保存在 Google 云存储的存储桶中。我知道问题出在 Android 应用程序中我的方法发出的 POST 请求,因为我已经使用 Postman 进行了测试并使其正常运行。所以我的应用程序中的以下代码有问题:
public void uploadFile(String uploadUrl, String filename, String newFileName) throws IOException {
FileInputStream fileInputStream = new FileInputStream(new File(filename));
URL url = new URL(uploadUrl);
connection = (HttpURLConnection) url.openConnection();
// Allow Inputs & Outputs.
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
// Set HTTP method to POST.
connection.setRequestMethod("POST");
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
outputStream = new DataOutputStream(connection.getOutputStream() );
outputStream.writeBytes(twoHyphens + boundary + lineEnd);
outputStream.writeBytes("Content-Disposition: form-data; name=\"img\";filename=\"" + filename + "\"" + lineEnd);
outputStream.writeBytes(lineEnd);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
// Read file
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0) {
outputStream.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
outputStream.writeBytes(lineEnd);
outputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
// Responses from the server (code and message)
int serverResponseCode = connection.getResponseCode();
String serverResponseMessage = connection.getResponseMessage();
System.out.println(serverResponseMessage);
System.out.println(serverResponseCode);
fileInputStream.close();
outputStream.flush();
outputStream.close();
}
我已经测试过所有参数都是100%正确的,所以你不用担心。
如果您需要查看来自网络服务的 PHP 代码以接收请求,这里是:
<?php
$img = $_FILES['img']['tmp_name'];
move_uploaded_file($img, 'gs://routeimages/yeeeeeeees.jpg');
echo "done";
?>
此代码中的问题可能出在哪里?
额外
除了file/image,我还需要添加一些文字。如何将此添加到请求中?
为什么不使用 Volley 库?它的方式更容易和清洁。像这个例子:
private void uploadImage(){
//Showing the progress dialog
final ProgressDialog loading = ProgressDialog.show(this,"Uploading...","Please wait...",false,false);
StringRequest stringRequest = new StringRequest(Request.Method.POST, UPLOAD_URL,
new Response.Listener<String>() {
@Override
public void onResponse(String s) {
//Disimissing the progress dialog
loading.dismiss();
//Showing toast message of the response
Toast.makeText(MainActivity.this, s , Toast.LENGTH_LONG).show();
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
//Dismissing the progress dialog
loading.dismiss();
//Showing toast
Toast.makeText(MainActivity.this, volleyError.getMessage().toString(), Toast.LENGTH_LONG).show();
}
}){
@Override
protected Map<String, String> getParams() throws AuthFailureError {
//Converting Bitmap to String
String image = getStringImage(bitmap);
//Getting Image Name
String name = editTextName.getText().toString().trim();
//Creating parameters
Map<String,String> params = new Hashtable<String, String>();
//Adding parameters
params.put(KEY_IMAGE, image);
params.put(KEY_NAME, name);
//returning parameters
return params;
}
};
//Creating a Request Queue
RequestQueue requestQueue = Volley.newRequestQueue(this);
//Adding request to the queue
requestQueue.add(stringRequest);
}
您发送的图像文件似乎丢失 Content-type
。
查看以下用于发送文件的 HTTP Post header
Content-type: multipart/form-data, boundary=AaB03x
--AaB03x
content-disposition: form-data; name="pics", filename="file2.gif"
Content-type: image/gif
Content-Transfer-Encoding: binary
...contents of file2.gif...
--AaB03x--
所以你需要在你的代码中添加 Content-type
属性 如下:
outputStream = new DataOutputStream(connection.getOutputStream() );
outputStream.writeBytes(twoHyphens + boundary + lineEnd);
outputStream.writeBytes("Content-Disposition: form-data; name=\"img\";filename=\"" + filename + "\"" + lineEnd);
outputStream.writeBytes("Content-type: image/gif" + lineEnd); // or whatever format you are sending.
outputStream.writeBytes("Content-Transfer-Encoding: binary" + lineEnd);
outputStream.writeBytes(lineEnd);
我希望这段代码可以帮助您解决问题。
补充:除了file/image,我还需要添加一些文字。如何将此添加到请求中?
要发送一些额外的参数(一些文本),请查看以下发送图像和文本参数的 http 格式:
Content-type: multipart/form-data, boundary=AaB03x
--AaB03x
content-disposition: form-data; name="pics", filename="file2.gif"
Content-type: image/gif
Content-Transfer-Encoding: binary
...contents of file2.gif...
--AaB03x--
content-disposition: form-data; name="field1"
Joe Blow
--AaB03x
我希望你现在可以在上面的图片上传说明和这种格式的帮助下编写额外参数的代码。
我在从我的 Android 应用程序向我的 Web 服务(Google 云和 PHP)发出正确的 POST 请求时遇到一些问题。
当我尝试从 Android 发送图像时,它 returns 收到“200 OK”响应,但图像未保存在 Google 云存储的存储桶中。我知道问题出在 Android 应用程序中我的方法发出的 POST 请求,因为我已经使用 Postman 进行了测试并使其正常运行。所以我的应用程序中的以下代码有问题:
public void uploadFile(String uploadUrl, String filename, String newFileName) throws IOException {
FileInputStream fileInputStream = new FileInputStream(new File(filename));
URL url = new URL(uploadUrl);
connection = (HttpURLConnection) url.openConnection();
// Allow Inputs & Outputs.
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
// Set HTTP method to POST.
connection.setRequestMethod("POST");
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
outputStream = new DataOutputStream(connection.getOutputStream() );
outputStream.writeBytes(twoHyphens + boundary + lineEnd);
outputStream.writeBytes("Content-Disposition: form-data; name=\"img\";filename=\"" + filename + "\"" + lineEnd);
outputStream.writeBytes(lineEnd);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
// Read file
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
while (bytesRead > 0) {
outputStream.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}
outputStream.writeBytes(lineEnd);
outputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
// Responses from the server (code and message)
int serverResponseCode = connection.getResponseCode();
String serverResponseMessage = connection.getResponseMessage();
System.out.println(serverResponseMessage);
System.out.println(serverResponseCode);
fileInputStream.close();
outputStream.flush();
outputStream.close();
}
我已经测试过所有参数都是100%正确的,所以你不用担心。
如果您需要查看来自网络服务的 PHP 代码以接收请求,这里是:
<?php
$img = $_FILES['img']['tmp_name'];
move_uploaded_file($img, 'gs://routeimages/yeeeeeeees.jpg');
echo "done";
?>
此代码中的问题可能出在哪里?
额外
除了file/image,我还需要添加一些文字。如何将此添加到请求中?
为什么不使用 Volley 库?它的方式更容易和清洁。像这个例子:
private void uploadImage(){
//Showing the progress dialog
final ProgressDialog loading = ProgressDialog.show(this,"Uploading...","Please wait...",false,false);
StringRequest stringRequest = new StringRequest(Request.Method.POST, UPLOAD_URL,
new Response.Listener<String>() {
@Override
public void onResponse(String s) {
//Disimissing the progress dialog
loading.dismiss();
//Showing toast message of the response
Toast.makeText(MainActivity.this, s , Toast.LENGTH_LONG).show();
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
//Dismissing the progress dialog
loading.dismiss();
//Showing toast
Toast.makeText(MainActivity.this, volleyError.getMessage().toString(), Toast.LENGTH_LONG).show();
}
}){
@Override
protected Map<String, String> getParams() throws AuthFailureError {
//Converting Bitmap to String
String image = getStringImage(bitmap);
//Getting Image Name
String name = editTextName.getText().toString().trim();
//Creating parameters
Map<String,String> params = new Hashtable<String, String>();
//Adding parameters
params.put(KEY_IMAGE, image);
params.put(KEY_NAME, name);
//returning parameters
return params;
}
};
//Creating a Request Queue
RequestQueue requestQueue = Volley.newRequestQueue(this);
//Adding request to the queue
requestQueue.add(stringRequest);
}
您发送的图像文件似乎丢失 Content-type
。
查看以下用于发送文件的 HTTP Post header
Content-type: multipart/form-data, boundary=AaB03x
--AaB03x
content-disposition: form-data; name="pics", filename="file2.gif"
Content-type: image/gif
Content-Transfer-Encoding: binary
...contents of file2.gif...
--AaB03x--
所以你需要在你的代码中添加 Content-type
属性 如下:
outputStream = new DataOutputStream(connection.getOutputStream() );
outputStream.writeBytes(twoHyphens + boundary + lineEnd);
outputStream.writeBytes("Content-Disposition: form-data; name=\"img\";filename=\"" + filename + "\"" + lineEnd);
outputStream.writeBytes("Content-type: image/gif" + lineEnd); // or whatever format you are sending.
outputStream.writeBytes("Content-Transfer-Encoding: binary" + lineEnd);
outputStream.writeBytes(lineEnd);
我希望这段代码可以帮助您解决问题。
补充:除了file/image,我还需要添加一些文字。如何将此添加到请求中? 要发送一些额外的参数(一些文本),请查看以下发送图像和文本参数的 http 格式:
Content-type: multipart/form-data, boundary=AaB03x
--AaB03x
content-disposition: form-data; name="pics", filename="file2.gif"
Content-type: image/gif
Content-Transfer-Encoding: binary
...contents of file2.gif...
--AaB03x--
content-disposition: form-data; name="field1"
Joe Blow
--AaB03x
我希望你现在可以在上面的图片上传说明和这种格式的帮助下编写额外参数的代码。