如何使用 okHttp 读取从 resteasy 发送到 android 的多部分响应?
How to read multipart response, sent from resteasy to android, using okHttp?
我想从 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();
.......
}
谁能帮我解决这个问题。我从 2 天起就被困在这里。我做错了什么。
试试这个:
//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);
}
您是否可能将 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>
您可以执行以下操作:
- 在后台运行创建一个异步任务
- 使用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
}
}
}
我想从 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();
.......
}
谁能帮我解决这个问题。我从 2 天起就被困在这里。我做错了什么。
试试这个:
//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);
}
您是否可能将 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>
您可以执行以下操作:
- 在后台运行创建一个异步任务
- 使用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
}
}
}