使用OkHttp在PHP服务器上上传文件,出错吗?

时间:2019-06-14 19:07:45

标签: java android okhttp

因此,首先,Android应用程序具有权限和库设置,更不用说PHP服务器已更新了php.ini文件以能够上传文件。

概念是输入函数的文件路径

    public String postImage (String imagePath) {

    result = ""+ System.currentTimeMillis();
    RequestBody requestBody = new MultipartBody.Builder()
            .setType(MultipartBody.FORM)
            .addFormDataPart("title", "result")
            .addFormDataPart("image", result + ".png",
                    RequestBody.create(MEDIA_TYPE_PNG, new File(imagePath)))
            .build();

    Request request = new Request.Builder()
            .url("http://192.168.0.17/addImage.php")
            .post(requestBody)
            .build();

    client.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            e.printStackTrace();
        }
        @Override
        public void onResponse(Call call, Response response) throws IOException {
            if (response.isSuccessful()) {
                result = response.body().string();
            }
        }
    });
    return result;
}

然后服务器具有该文件,该文件获取名为“ addImage.php”的功能的POST。

<?php

if ($_SERVER['REQUEST_METHOD']=='POST') {
    $target_dir = "images/";
    $target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
    $uploadOk = 1;
    $imageFileType =  strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
    // Check if image file is a actual image or fake image
    $check = getimagesize($_FILES["fileToUpload"]["tmp_name"]);
    if($check !== false) {
        echo "File is an image - " . $check["mime"] . ".";
        $uploadOk = 1;
    } else {
        echo "File is not an image.";
        $uploadOk = 0;
    }
}?>

但是由于某些原因,我会收到此错误

    W/System.err: java.io.FileNotFoundException: content:/com.google.android.apps.photos.contentprovider/-1/1/content%3A%2F%2Fmedia%2Fexternal%2Fimages%2Fmedia%2F77/ORIGINAL/NONE/294934663 (No such file or directory)
        at java.io.FileInputStream.open0(Native Method)
        at java.io.FileInputStream.open(FileInputStream.java:231)
        at java.io.FileInputStream.<init>(FileInputStream.java:165)
        at okio.Okio.source(Okio.kt:194)
        at okhttp3.RequestBody$Companion$toRequestBody$3.writeTo(RequestBody.kt:162)
        at okhttp3.MultipartBody.writeOrCountBytes(MultipartBody.kt:156)
        at okhttp3.MultipartBody.writeTo(MultipartBody.kt:92)
        at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.kt:59)
W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
        at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:37)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
        at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:82)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
        at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:84)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
        at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:71)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
        at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.kt:184)
        at okhttp3.RealCall$AsyncCall.run(RealCall.kt:136)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:764)
D/EGL_emulation: eglMakeCurrent: 0xe82c59a0: ver 3 1 (tinfo 0xe0ab13a0)
D/EGL_emulation: eglMakeCurrent: 0xe82c59a0: ver 3 1 (tinfo 0xe0ab13a0)
D/EGL_emulation: eglMakeCurrent: 0xe82c59a0: ver 3 1 (tinfo 0xe0ab13a0)
D/EGL_emulation: eglMakeCurrent: 0xe82c59a0: ver 3 1 (tinfo 0xe0ab13a0)
Application terminated.

该错误表明给定的图像路径为(No such file or directory),但是我很容易选择它并将其显示在Glide上。 Android Studio还告诉我,RequestBody.create()也已被弃用,但是OkHttp食谱页面显示了它的使用情况。

编辑:为澄清起见,该错误不是来自PHP,而是来自Java中的OkHttp或FileInputStream,但是我不知道为什么

Edit2:我已经意识到错误是给定的图像路径不是File()可以识别的有效路径的事实,但是在没有错误的情况下,我无法获得服务器上的任何文件。有什么帮助吗?

1 个答案:

答案 0 :(得分:0)

提供所有详细信息以及问题的根源。

首先一切都可以正常工作。

当提供的图像路径完全错误时出现了原始问题,这是由用户输入提供的,但是Glide可以轻松显示它,所以我确实显示了它,然后将drawable转换为位图,然后将其转换为byte []最后使用FileOutStream将图像保存到创建的缓存中(缓存在onStop()函数中清除了),最后只需使用this.getCachedir()抓取图像路径。

构建Multipart.Builder和.addFormDataPart("fileToUpload", result + ".png", RequestBody.create(MEDIA_TYPE_PNG, new File(imagePath)))

通过这种方式,PHP服务器可以获取"fileToUpload"并将其存储,而且PHP文件还需要一个目录来存储图像,在这种情况下,该目录为“ images /”,因此必须预先创建该目录,因此PHP文件可以识别并将其存储在其中。

对于想要使用同一库并尝试上传图像的任何人,请使用以下代码

对于Java:

    public String postImage (String imagePath) {

    result = ""+ System.currentTimeMillis();
    RequestBody requestBody = new MultipartBody.Builder()
            .setType(MultipartBody.FORM)
            .addFormDataPart("fileToUpload", result + ".png",
                    RequestBody.create(MEDIA_TYPE_PNG, new File(imagePath)))
            .build();

    Request request = new Request.Builder()
            .url("http://192.168.0.17/addImage.php")
            .post(requestBody)
            .build();

    client.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            e.printStackTrace();
        }
        @Override
        public void onResponse(Call call, Response response) throws IOException {
            if (response.isSuccessful()) {
                result = response.body().string();
            }
        }
    });
    return "http://192.168.0.17/uploads/"+result;
}

PHP服务器端:

    <?php

if ($_SERVER['REQUEST_METHOD']=='POST') {
    $target_dir = "images/";
    $target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
    $uploadOk = 1;
    $imageFileType =  strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
    // Check if image file is a actual image or fake image
    $check = getimagesize($_FILES["fileToUpload"]["tmp_name"]);
    if($check !== false) {
        echo "File is an image - " . $check["mime"] . ".";
        $uploadOk = 1;
    } else {
        echo "File is not an image.";
        $uploadOk = 0;
    }
}?>

请记住要在Android应用上设置权限,并设置php.ini以允许文件上传。