Файл неправильно загружен с помощью POST-запроса - PullRequest
0 голосов
/ 03 апреля 2020

Я пытаюсь загрузить файл .zip с телефона Android с помощью POST-запроса. Я нашел в некоторых поисках через 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 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";

}}

Я в основном реализовал его с this , this в качестве шаблона.

Что-то не так делаю? Как еще можно загрузить файлы таким способом?

Использование Бессонница Я могу отправлять файлы, и там Content-Type также является application / octet-stream.

1 Ответ

0 голосов
/ 06 апреля 2020

Мне удалось заставить его работать. Проблема была на моей 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;
    }

}

}

...