文件未能通过POST请求正确上传。

huangapple go评论95阅读模式
英文:

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&lt;String, String, String&gt; {

@Override
protected String doInBackground(String... params) {
    String zipPath = params[0];
    String zipName = params[1];
    String serverUrl = &quot;http://192.168.1.109:5000&quot;+&quot;/files/&quot;+zipName;
    File file = new File(zipPath+zipName);
    Log.d(&quot;File name&quot;, &quot;zipName: &quot;+zipName+&quot; file.getName(): &quot;+file.getName());

    // TODO file is not send properly...
    RequestBody postBody = new MultipartBody.Builder()
            .setType(MultipartBody.FORM)
            .addFormDataPart(zipName, file.getName(),
                    RequestBody.create(MediaType.parse(&quot;application/octet-stream&quot;), file))
            .build();

    OkHttpClient client = new OkHttpClient();

    Request request = new Request.Builder()
            .url(serverUrl)
            .post(postBody)
            // TODO insert API-key here
            .addHeader(&quot;API-key&quot;, &quot;&lt;my-api-key&gt;&quot;)
            .build();


    try {
        Response response = client.newCall(request).execute();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return &quot;Request Submitted&quot;;
   
}}

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(&quot;/files&quot;, methods=[&quot;POST&quot;])
def post_file():
&quot;&quot;&quot;Upload a file.&quot;&quot;&quot;
zipfile = request.files[&quot;zip&quot;]
filename = secure_filename(zipfile.filename)
# Check if user has correct key
user_key = request.headers.get(&quot;API-key&quot;)
if user_key not in ALLOWED_KEYS:
return f&quot;Permission denied. Key &#39;{user_key}&#39; has no access.&quot;, 401
if &quot;/&quot; in filename:
# Return 400 BAD REQUEST
abort(400, &quot;no subdirectories directories allowed&quot;)
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)), &quot;wb&quot;) as fp:	    
#     fp.write(request.data)
# Return 201 CREATED
return &quot;Successfully uploaded file.&quot;, 201

Here the code of my Android side:

public class FileSender extends AsyncTask&lt;String, Boolean, Boolean&gt; {
@Override
protected Boolean doInBackground(String... params) {
String zipPath = params[0];
String zipName = params[1];
// TODO put ip in env-variable
String serverUrl = &quot;http://IP:Port&quot;+&quot;/files&quot;;
File file = new File(zipPath+zipName);
Log.d(&quot;File name&quot;, &quot;zipName: &quot;+zipName+&quot; file.getName(): &quot;+file.getName());
RequestBody postBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart(&quot;zip&quot;, file.getName(),
RequestBody.create(MediaType.parse(&quot;application/zip&quot;), file))
.build();
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(serverUrl)
.post(postBody)
// TODO insert API-key here
.addHeader(&quot;API-key&quot;, &quot;&lt;API-Key&gt;&quot;)
.build();
try {
Response response = client.newCall(request).execute();
Log.d(&quot;SendToServer&quot;, &quot;Worked: &quot;+response.body().string());
return true;
} catch (IOException e) {
Log.d(&quot;SendToServer&quot;, &quot;Error: &quot;+e.toString());
e.printStackTrace();
return false;
}
}

}

huangapple
  • 本文由 发表于 2020年4月3日 19:15:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/61010644.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定