【问题标题】:How to read multipart response, sent from resteasy to android, using okHttp?如何使用okHttp读取从resteasy发送到android的多部分响应?
【发布时间】:2017-07-03 14:23:45
【问题描述】:

我想将文件列表(在我的情况下为图像)从 JBoss 服务器上传到 android。 我是通过下面的书面代码这样做的:

@GET
@Path("/report/{filename}")
@Produces({MediaType.MULTIPART_FORM_DATA})
public MultipartFormDataOutput getReport(@PathParam("filename") String filename, @Context HttpServletRequest request) {
    try {
        String token = request.getHeader("Authorization");
        List<File> file = processImage.getImage(filename,token);
        MultipartFormDataOutput output = new MultipartFormDataOutput();
        for(File image: file){
        System.out.println("class of this" +image + "MMMM" +image.exists());
        output.addPart(image, new MediaType("image","jpg"));
        }
        return output;

    } .....
      .......
}

在 Android 端,我想读取响应(多部分形式的文件)。我正在使用 okHttp 进行连接。 在互联网上搜索了很多我尝试下面的代码来读取多部分响应,但它不起作用。似乎没有从流中读取任何内容。

ByteArrayDataSource ds = new ByteArrayDataSource(response.body().byteStream(), "multipart/form-data");
            MimeMultipart multipart = new MimeMultipart(ds);
            BodyPart jsonPart = multipart.getBodyPart(0);

            System.out.println("Response body = " + jsonPart.getInputStream());
            File reportFile = new File(Environment.getExternalStorageDirectory() + File.separator + "downloadedFile.jpg");
            InputStream is = jsonPart.getInputStream();
            FileOutputStream fileOutputStream = null;
            try {
                fileOutputStream = new FileOutputStream(reportFile);
                byte[] buffer = new byte[MEGABYTE];
                int bufferLength = 0;

                while ((bufferLength = is.read(buffer)) > 0) {
                    fileOutputStream.write(buffer, 0, bufferLength);
                }
                is.close();
                fileOutputStream.close();   
                  .......
            }

谁能帮我解决这个问题。我被困在这里两天了。我做错了什么。

【问题讨论】:

标签: android jax-rs multipartform-data resteasy okhttp


【解决方案1】:

您可以执行以下操作:

  • 创建一个在后台运行的异步任务
  • 使用 okhttp3.Request 创建请求
  • 创建 OkHttpClient 发送请求并将响应保存在 okHttp3 Response 中
  • 然后从okhttp3.ResponseBody获取响应体,使用InputStreamReader和BufferedReader读取文件。

类似下面的东西应该可以工作:

private class FileTask extends AsyncTask<Void, Void, Void> {
   private File file = null;
    @Override
    protected Void doInBackground(Void... params) {

        okhttp3.Request request = new okhttp3.Request.Builder()
                .url("Your URL for getReport()")
                .get()
                .build();
        OkHttpClient okHttpClient = new OkHttpClient.Builder().
                        connectTimeout(80, TimeUnit.SECONDS)
                        .writeTimeout(80, TimeUnit.SECONDS)
                        .readTimeout(80, TimeUnit.SECONDS)
                        .build();


        try {
            Response response = okHttpClient.newCall(request).execute();
            okhttp3.ResponseBody in = response.body();
            InputStream is = in.byteStream();
            InputStreamReader inputStreamReader = new InputStreamReader(is);
            BufferedReader buffReader = new BufferedReader(inputStreamReader);

            file = new File(Environment.getExternalStorageDirectory() + File.separator + "filename.txt"); //Your output file
            OutputStream output = new FileOutputStream(file);
            BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(output);


            String line=buffReader.readLine();
            while ((line=buffReader.readLine()) != null) {
                output.write(line.getBytes());
                output.write('\n');
            }
            buffReader.close();
            output.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        //do post execution steps
        }
    }
}

【讨论】:

    【解决方案2】:

    您是否可能将 HttpLoggingInterceptor 与 setLevel(HttpLoggingInterceptor.Level.BODY) 一起使用?我使用您的代码成功解析了多部分响应。但是,一旦我将级别从 HEADERS 更改为 BODY,该代码就不再起作用,并且就像它没有从流中读取任何内容一样。我已经报告了这个问题:https://github.com/square/okhttp/issues/3269

    顺便说一句,感谢您提供示例代码,让我可以使用 OkHttp 解析多部分正文。对于可能出现的其他人,我必须将其添加到我的 maven pom.xml 中:

        <dependency>
            <groupId>com.sun.mail</groupId>
            <artifactId>javax.mail</artifactId>
            <version>1.5.6</version>
        </dependency>
    

    【讨论】:

    • 谢谢我得到了解决方案。即将发布
    【解决方案3】:

    试试这个:

     //first you should convert image into bytearray
    
    
     VolleyMultipartRequest multipartRequest = new VolleyMultipartRequest(Request.Method.POST, url, new Response.Listener<NetworkResponse>() {
            @Override
            public void onResponse(NetworkResponse response) {
    
                System.out.println(" response"+response.data);
    
    
                String resultResponse = new String(response.data);
                System.out.println("-------------  response-----------------"+resultResponse);
    
                try {
                    JSONObject jsonObject = new JSONObject(resultResponse);
                    sStatus = jsonObject.getString("status");
    
    
                    } else {
    
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                dialog.dismiss();
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
    
                dialog.dismiss();
    
                NetworkResponse networkResponse = error.networkResponse;
                String errorMessage = "Unknown error";
                if (networkResponse == null) {
                    if (error.getClass().equals(TimeoutError.class)) {
                        errorMessage = "Request timeout";
                    } else if (error.getClass().equals(NoConnectionError.class)) {
                        errorMessage = "Failed to connect server";
                    }
                } else {
                    String result = new String(networkResponse.data);
                    try {
                        JSONObject response = new JSONObject(result);
                        String status = response.getString("status");
                        String message = response.getString("message");
    
                        Log.e("Error Status", status);
                        Log.e("Error Message", message);
    
                        if (networkResponse.statusCode == 404) {
                            errorMessage = "Resource not found";
                        } else if (networkResponse.statusCode == 401) {
                            errorMessage = message + " Please login again";
                        } else if (networkResponse.statusCode == 400) {
                            errorMessage = message + " Check your inputs";
                        } else if (networkResponse.statusCode == 500) {
                            errorMessage = message + " Something is getting wrong";
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
                Log.i("Error", errorMessage);
                error.printStackTrace();
            }
        }) {
    
            @Override
            protected Map<String, String> getParams() {
                Map<String, String> params = new HashMap<>();
                params.put("id",ID);
                System.out.println("id---------------"+ID);
                return params;
            }
    
            @Override
            protected Map<String, DataPart> getByteData() {
                Map<String, DataPart> params = new HashMap<>();
                params.put("image",new DataPart("imnage.jpg", byteArray));
    
                return params;
            }
        }
    
        AppController.getInstance().addToRequestQueue(multipartRequest);
    
    }
    

    【讨论】:

    • 您的响应使用了 VolleyMultipartRequest,它似乎依赖于 apache httpclient。问题是如何使用 okhttp 而不是 httpclient 来做到这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-19
    • 1970-01-01
    • 2014-04-25
    • 2017-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多