英文:
File is not correctly uploaded using POST-request
问题
我正在尝试使用POST请求从Android手机上传一个.zip文件。我通过浏览论坛找到了okhttp,应该会使这变得相当容易。
到达服务器的文件是一个具有正确名称的zip文件,但文件中没有任何内容(大小为0kb)。我怀疑在使用okhttp发送时,流没有正确刷新。
public class FileSender extends AsyncTask<String, String, String> {
@Override
protected String doInBackground(String... params) {
String zipPath = params[0];
String zipName = params[1];
String serverUrl = "http://192.168.1.109:5000" + "/files/" + zipName;
File file = new File(zipPath + zipName);
Log.d("File name", "zipName: " + zipName + " file.getName(): " + file.getName());
// TODO 文件未正确发送...
RequestBody postBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart(zipName, file.getName(),
RequestBody.create(MediaType.parse("application/octet-stream"), file))
.build();
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(serverUrl)
.post(postBody)
// TODO 在此处插入API密钥
.addHeader("API-key", "<my-api-key>")
.build();
try {
Response response = client.newCall(request).execute();
} catch (IOException e) {
e.printStackTrace();
}
return "请求已提交";
}
}
我做错了什么吗?还有其他上传文件的方法吗?
使用Insomnia,我可以发送文件,在那里Content-Type也是"application/octet-stream"。
英文:
I am trying to upload a .zip file from an Android phone using a POST-request. I found through some scouting through the forums okhttp which should make it quite easy.
The file that arrives at the server is a zip-file with the correct name, but there is no content in the file (it is 0kb). I suspect that the stream is not correctly flushed when sending by okhttp.
public class FileSender extends AsyncTask<String, String, String> {
@Override
protected String doInBackground(String... params) {
String zipPath = params[0];
String zipName = params[1];
String serverUrl = "http://192.168.1.109:5000"+"/files/"+zipName;
File file = new File(zipPath+zipName);
Log.d("File name", "zipName: "+zipName+" file.getName(): "+file.getName());
// TODO file is not send properly...
RequestBody postBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart(zipName, file.getName(),
RequestBody.create(MediaType.parse("application/octet-stream"), file))
.build();
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(serverUrl)
.post(postBody)
// TODO insert API-key here
.addHeader("API-key", "<my-api-key>")
.build();
try {
Response response = client.newCall(request).execute();
} catch (IOException e) {
e.printStackTrace();
}
return "Request Submitted";
}}
I basically implemented it with this, this as template.
Am I doing something wrong? What is another way to upload files this way?
Using Insomnia I am able to send files and there the Content-Type is also "application/octet-stream".
答案1
得分: 0
我设法使它工作了。问题出在我的Flask服务器端。以下是接受文件的代码:
@api.route("/files", methods=["POST"])
def post_file():
"""Upload a file."""
zipfile = request.files["zip"]
filename = secure_filename(zipfile.filename)
# Check if user has correct key
user_key = request.headers.get("API-key")
if user_key not in ALLOWED_KEYS:
return f"Permission denied. Key '{user_key}' has no access.", 401
if "/" in filename:
# Return 400 BAD REQUEST
abort(400, "no subdirectories directories allowed")
zipfile.save(os.path.join(UPLOAD_DIRECTORY, filename))
# Before I tried this (which does not work):
# with open(os.path.join(UPLOAD_DIRECTORY, secure_filename(filename)), "wb") as fp:
# fp.write(request.data)
# Return 201 CREATED
return "Successfully uploaded file.", 201
这是我Android端的代码:
public class FileSender extends AsyncTask<String, Boolean, Boolean> {
@Override
protected Boolean doInBackground(String... params) {
String zipPath = params[0];
String zipName = params[1];
// TODO put ip in env-variable
String serverUrl = "http://IP:Port"+"/files";
File file = new File(zipPath+zipName);
Log.d("File name", "zipName: "+zipName+" file.getName(): "+file.getName());
RequestBody postBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("zip", file.getName(),
RequestBody.create(MediaType.parse("application/zip"), file))
.build();
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(serverUrl)
.post(postBody)
// TODO insert API-key here
.addHeader("API-key", "<API-Key>")
.build();
try {
Response response = client.newCall(request).execute();
Log.d("SendToServer", "Worked: "+response.body().string());
return true;
} catch (IOException e) {
Log.d("SendToServer", "Error: "+e.toString());
e.printStackTrace();
return false;
}
}
}
英文:
I managed to make it work. The issue was on my Flask-server side. This is the code that accepts the file:
@api.route("/files", methods=["POST"])
def post_file():
"""Upload a file."""
zipfile = request.files["zip"]
filename = secure_filename(zipfile.filename)
# Check if user has correct key
user_key = request.headers.get("API-key")
if user_key not in ALLOWED_KEYS:
return f"Permission denied. Key '{user_key}' has no access.", 401
if "/" in filename:
# Return 400 BAD REQUEST
abort(400, "no subdirectories directories allowed")
zipfile.save(os.path.join(UPLOAD_DIRECTORY, filename))
# Before I tried this (which does not work):
# with open(os.path.join(UPLOAD_DIRECTORY, secure_filename(filename)), "wb") as fp:
# fp.write(request.data)
# Return 201 CREATED
return "Successfully uploaded file.", 201
Here the code of my Android side:
public class FileSender extends AsyncTask<String, Boolean, Boolean> {
@Override
protected Boolean doInBackground(String... params) {
String zipPath = params[0];
String zipName = params[1];
// TODO put ip in env-variable
String serverUrl = "http://IP:Port"+"/files";
File file = new File(zipPath+zipName);
Log.d("File name", "zipName: "+zipName+" file.getName(): "+file.getName());
RequestBody postBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("zip", file.getName(),
RequestBody.create(MediaType.parse("application/zip"), file))
.build();
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(serverUrl)
.post(postBody)
// TODO insert API-key here
.addHeader("API-key", "<API-Key>")
.build();
try {
Response response = client.newCall(request).execute();
Log.d("SendToServer", "Worked: "+response.body().string());
return true;
} catch (IOException e) {
Log.d("SendToServer", "Error: "+e.toString());
e.printStackTrace();
return false;
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论