使用Retrofit发送图像文件帖子?

时间:2014-11-30 02:18:01

标签: php android web-services retrofit

我正在测试一些使用Retrofit库发送图像的方法。在这里的Retrofit文档中:http://square.github.io/retrofit/有一种使用@MultiPart注释的方法。 我尝试像文档一样使用,但仍然不适合我。

我该怎么做?

我在这里尝试。

Web服务php文件

if($_REQUEST["uploadfile"] == "add"){
    $uploaddir = 'C:\Users\fernando\Pictures';
    $uploadfile = $uploaddir . $_FILES['userfile']['name'];

    $response = array();
    //param
    $response["nome"] = $_REQUEST["nome"];


    if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploaddir . $_FILES['userfile']['name'])) {
        $response["msg"] = "O arquivo é valido e foi carregado com sucesso. Aqui esta alguma informação:\n";
        print_r($_FILES);
    }  else {
        $response["msg"] = "Possivel ataque de upload! Aqui esta alguma informação:\n";
        print_r($_FILES);
    }
    $json = json_encode($response);
    echo $json;
}

Usuario的听众

public interface UsuarioListener {

    //send an image with params with Post
    @Multipart
    @POST("/android/login.php")
    void setUserImage(
            @QueryMap Map<String, String> params,
            @Part("pathImage") TypedFile file,          
            Callback<JsonElement> response);

}

活动

btnEnviar.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                setUserImage();
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == RESULT_LOAD_IMAGE && 
            resultCode == RESULT_OK && 
            null != data) {
            Uri selectedImage = data.getData();
            String[] filePathColumn = { MediaStore.Images.Media.DATA };

            Cursor cursor = getContentResolver().query(selectedImage,
                    filePathColumn, null, null, null);
            cursor.moveToFirst();

            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
            pathImage = cursor.getString(columnIndex);
            cursor.close();
        }
    }

    public void setUserImage() {
        HashMap<String, String> params = new HashMap<String, String>();
        params.put("nome", "Fernando Paiva Campos");

        RestAdapter adapter = new RestAdapter.Builder()
                            .setLogLevel(RestAdapter.LogLevel.FULL)
                            .setEndpoint(END_POINT).build();
        UsuarioListener listener = adapter.create(UsuarioListener.class);

        TypedFile image = new TypedFile("image/jpg", new File(pathImage));
        listener.setUserImage(
                              params,
                              image,
                              new Callback<JsonElement>() {
            @Override
            public void success(JsonElement arg0, Response arg1) {
                Log.i("JSON_ELEMENT:", arg0.toString() + "");
            }

            @Override
            public void failure(RetrofitError arg0) {
                Log.e("ERROR:", arg0.getLocalizedMessage());

            }
        });     
    }

异常

  

E / ERROR:(5200):com.google.gson.JsonSyntaxException:com.google.gson.stream.MalformedJsonException:使用JsonReader.setLenient(true)接受第1行第6列的格式错误的JSON

2 个答案:

答案 0 :(得分:1)

看起来上面引用的错误与你的php输出有关。目前还不清楚上传是否成功,但您的响应是无效的JSON,因为在您回显JSON响应之前,还会打印出$_FILES的值。尝试使用php文件中的以下代码注释掉这些行。

print_r($_FILES);

答案 1 :(得分:0)

您的问题有两处更正:

在此代码中:

public interface UsuarioListener {

    //send an image with params with Post
    @Multipart
    @POST("/android/login.php")
    void setUserImage(
        @QueryMap Map<String, String> params,
        // the @Part has the parameter "pathImage". 
        // You should pass this in your php code.
        @Part("pathImage") TypedFile file, 
        Callback<JsonElement> response);
}

所以你的php代码应该像:

if($_REQUEST["uploadfile"] == "add"){
$uploaddir = 'C:\Users\fernando\Pictures';
$uploadfile = $uploaddir . $_FILES['userfile']['name'];

$response = array();
//param
$response["nome"] = $_REQUEST["nome"];

if (move_uploaded_file($_FILES['pathImage']['tmp_name'], $uploaddir . $_FILES['pathImage']['name']))

您的Retrofit客户端的最终更正:

TypedFile typedImage = new TypedFile("application/octet-stream", photo);

有关详细信息,您可以在我的答案中找到类似问题: Retrofit Multipart Upload Image failed