使用okhttp上传文件

时间:2015-05-20 02:28:54

标签: java android okhttp

我正在完成这个使用okhttp与web服务进行通信的项目。

对于常规GET和POST,一切正常,但我无法正确上传文件。

okhttp文档非常缺乏这些主题,我在这里或任何地方找到的所有东西似乎都不适用于我的情况。

它应该很简单:我必须发送文件和一些字符串值。但我无法弄清楚如何做到这一点。

根据我发现的一些样本,我首先尝试了这个:

RequestBody requestBody = new MultipartBuilder().type(MultipartBuilder.FORM)
    .addFormDataPart("group", getGroup())
    .addFormDataPart("type", getType())
    .addFormDataPart("entity", Integer.toString(getEntity()))
    .addFormDataPart("reference", Integer.toString(getReference()))
    .addPart(Headers.of("Content-Disposition", "form-data; name=\"task_file\""), RequestBody.create(MediaType.parse("image/png"), getFile()))
    .build();

它给我一个“400错误请求”错误。

所以我从okhttp食谱中尝试了这个:

RequestBody requestBody = new MultipartBuilder().type(MultipartBuilder.FORM)
    .addPart(Headers.of("Content-Disposition", "form-data; name=\"group\""), RequestBody.create(null, getGroup()))
    .addPart(Headers.of("Content-Disposition", "form-data; name=\"type\""), RequestBody.create(null, getType()))
    .addPart(Headers.of("Content-Disposition", "form-data; name=\"entity\""), RequestBody.create(null, Integer.toString(getEntity())))
    .addPart(Headers.of("Content-Disposition", "form-data; name=\"reference\""), RequestBody.create(null, Integer.toString(getReference())))
    .addPart(Headers.of("Content-Disposition", "form-data; name=\"task_file\""), RequestBody.create(MediaType.parse("image/png"), getFile()))
    .build();

同样的结果。

不知道还有什么可以尝试或调查这个。

请求使用以下代码完成:

// adds the required authentication token
Request request = new Request.Builder().url(getURL()).addHeader("X-Auth-Token", getUser().getToken().toString()).post(requestBody).build();
Response response = client.newCall(request).execute();

但我很确定问题是如何建立请求体。

我做错了什么?

编辑:顺便说一句,上面的“getFile()”返回一个File对象。其余参数都是字符串和整数。

4 个答案:

答案 0 :(得分:20)

我在初次发布后找到了自己的问题答案。

我会把它留在这里,因为它对其他人有用,因为有很多okhttp上传示例:

RequestBody requestBody = new MultipartBuilder().type(MultipartBuilder.FORM)
        .addFormDataPart("group", getGroup())
        .addFormDataPart("type", getType())
        .addFormDataPart("entity", Integer.toString(getEntity()))
        .addFormDataPart("reference", Integer.toString(getReference()))
        .addFormDataPart("task_file", "file.png", RequestBody.create(MediaType.parse("image/png"), getFile()))
                                                .build();

没有理由将“addPart”与“Headers.of”等一起使用,就像在食谱中一样,addFormDataPart可以解决问题。

对于文件字段本身,它需要3个参数:name,filename,然后是文件体。就是这样。

答案 1 :(得分:6)

我刚刚更改addFormDataPart而不是addPart,最后使用以下代码解决了我的问题:

  /**
     * Upload Image
     *
     * @param memberId
     * @param sourceImageFile
     * @return
     */
    public static JSONObject uploadImage(String memberId, String sourceImageFile) {

        try {
            File sourceFile = new File(sourceImageFile);

            Log.d(TAG, "File...::::" + sourceFile + " : " + sourceFile.exists());

            final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");

            RequestBody requestBody = new MultipartBuilder()
                    .type(MultipartBuilder.FORM)
                    .addFormDataPart("member_id", memberId)
                    .addFormDataPart("file", "profile.png", RequestBody.create(MEDIA_TYPE_PNG, sourceFile))
                    .build();

            Request request = new Request.Builder()
                    .url(URL_UPLOAD_IMAGE)
                    .post(requestBody)
                    .build();

            OkHttpClient client = new OkHttpClient();
            Response response = client.newCall(request).execute();
            return new JSONObject(response.body().string());

        } catch (UnknownHostException | UnsupportedEncodingException e) {
            Log.e(TAG, "Error: " + e.getLocalizedMessage());
        } catch (Exception e) {
            Log.e(TAG, "Other Error: " + e.getLocalizedMessage());
        }
        return null;
    }

答案 2 :(得分:2)

OKHTTP 3 + 中的

使用此 AsyncTask

<强> SignupWithImageTask

  public class SignupWithImageTask extends AsyncTask<String, Integer, String> {

        ProgressDialog progressDialog;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            progressDialog = new ProgressDialog(SignupActivity.this);
            progressDialog.setMessage("Please Wait....");
            progressDialog.show();
        }

        @Override
        protected String doInBackground(String... str) {

            String res = null;
            try {
//                String ImagePath = str[0];
                String name = str[0], email = str[1], dob = str[2], IMEI = str[3], phone = str[4], ImagePath = str[5];

                File sourceFile = new File(ImagePath);

                Log.d("TAG", "File...::::" + sourceFile + " : " + sourceFile.exists());

                final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/*");

                String filename = ImagePath.substring(ImagePath.lastIndexOf("/") + 1);

                /**
                 * OKHTTP2
                 */
//            RequestBody requestBody = new MultipartBuilder()
//                    .type(MultipartBuilder.FORM)
//                    .addFormDataPart("member_id", memberId)
//                    .addFormDataPart("file", "profile.png", RequestBody.create(MEDIA_TYPE_PNG, sourceFile))
//                    .build();

                /**
                 * OKHTTP3
                 */
                RequestBody requestBody = new MultipartBody.Builder()
                        .setType(MultipartBody.FORM)
                        .addFormDataPart("image", filename, RequestBody.create(MEDIA_TYPE_PNG, sourceFile))
                        .addFormDataPart("result", "my_image")
                        .addFormDataPart("name", name)
                        .addFormDataPart("email", email)
                        .addFormDataPart("dob", dob)
                        .addFormDataPart("IMEI", IMEI)
                        .addFormDataPart("phone", phone)
                        .build();

                Request request = new Request.Builder()
                        .url(BASE_URL + "signup")
                        .post(requestBody)
                        .build();

                OkHttpClient client = new OkHttpClient();
                okhttp3.Response response = client.newCall(request).execute();
                res = response.body().string();
                Log.e("TAG", "Response : " + res);
                return res;

            } catch (UnknownHostException | UnsupportedEncodingException e) {
                Log.e("TAG", "Error: " + e.getLocalizedMessage());
            } catch (Exception e) {
                Log.e("TAG", "Other Error: " + e.getLocalizedMessage());
            }


            return res;

        }

        @Override
        protected void onPostExecute(String response) {
            super.onPostExecute(response);
            if (progressDialog != null)
                progressDialog.dismiss();

            if (response != null) {
                try {

                    JSONObject jsonObject = new JSONObject(response);


                    if (jsonObject.getString("message").equals("success")) {

                        JSONObject jsonObject1 = jsonObject.getJSONObject("data");

                        SharedPreferences settings = getSharedPreferences("preference", 0); // 0 - for private mode
                        SharedPreferences.Editor editor = settings.edit();
                        editor.putString("name", jsonObject1.getString("name"));
                        editor.putString("userid", jsonObject1.getString("id"));
                        editor.putBoolean("hasLoggedIn", true);
                        editor.apply();

                        new UploadContactTask().execute();

                        startActivity(new Intent(SignupActivity.this, MainActivity.class));
                    } else {
                        Toast.makeText(SignupActivity.this, "" + jsonObject.getString("message"), Toast.LENGTH_SHORT).show();
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            } else {
                Toast.makeText(SignupActivity.this, "Something Went Wrong", Toast.LENGTH_SHORT).show();
            }

        }
    }

答案 3 :(得分:0)

以下是使用okhttp3上传文件的方法。

      try {

          UpdateInformation("yourEmailAddress", filePath, sourceFile);

          } catch (IOException e) {
                        e.printStackTrace();
         }

    private void UploadInformation(String email, final String _filePath, final File file) throws IOException {


        runOnUiThread(new Runnable() {
            @Override
            public void run() {


            //show progress bar here

            }
        });


        OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(60, TimeUnit.SECONDS)
                .writeTimeout(60, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS)
                .build();





        String mime = getMimeType(_filePath);


        RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM)
                .addFormDataPart("file", file.getName(),
                        RequestBody.create(MediaType.parse(mime), file))
                .addFormDataPart("email", email)
                .build();





        okhttp3.Request request = new okhttp3.Request.Builder()
                .url("yourEndPointURL")
                .post(body)
                .addHeader("authorization", "yourEndPointToken")
                .addHeader("content-type", "application/json")
                .build();



        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                call.cancel();


                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {

                    //hide progress bar here

                    }
                });

            }

            @Override
            public void onResponse(Call call, okhttp3.Response response) throws IOException {


                try {

                    final String myResponse = response.body().string();


                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {

                    //hide progress bar here

                    //Cont from here
                    //Handle yourEndPoint Response.



                        }
                    });


                } catch (Exception e) {
                    e.printStackTrace();
                }


            }



        });
    }


private String getMimeType(String path) {
        FileNameMap fileNameMap = URLConnection.getFileNameMap();
        String contentTypeFor = fileNameMap.getContentTypeFor(path);
        if (contentTypeFor == null)
        {
            contentTypeFor = "application/octet-stream";
        }
        return contentTypeFor;
    }

希望这会有所帮助。