N4z*_*oth 28 upload android download retrofit
我正在尝试使用改进2来下载/上传文件,但找不到任何有关如何操作的教程示例.我的下载代码是:
@GET("documents/checkout")
public Call<File> checkout(@Query(value = "documentUrl") String documentUrl, @Query(value = "accessToken") String accessToken, @Query(value = "readOnly") boolean readOnly);
Run Code Online (Sandbox Code Playgroud)
和
Call<File> call = RetrofitSingleton.getInstance(serverAddress)
.checkout(document.getContentUrl(), apiToken, readOnly[i]);
call.enqueue(new Callback<File>() {
@Override
public void onResponse(Response<File> response,
Retrofit retrofit) {
String fileName = document.getFileName();
try {
System.out.println(response.body());
long fileLength = response.body().length();
InputStream input = new FileInputStream(response.body());
File path = Environment.getExternalStorageDirectory();
File file = new File(path, fileName);
BufferedOutputStream output = new BufferedOutputStream(
new FileOutputStream(file));
byte data[] = new byte[1024];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
total += count;
output.write(data, 0, count);
}
output.flush();
output.close();
} catch (IOException e) {
String logTag = "TEMPTAG";
Log.e(logTag, "Error while writing file!");
Log.e(logTag, e.toString());
}
}
@Override
public void onFailure(Throwable t) {
// TODO: Error handling
System.out.println(t.toString());
}
});
Run Code Online (Sandbox Code Playgroud)
我尝试过Call和Call,但似乎没有任何效果.
在正确设置标头和mime类型之后,服务器端代码将文件的字节写入HttpServletResponse的输出流.
我究竟做错了什么?
最后,上传代码:
@Multipart
@POST("documents/checkin")
public Call<String> checkin(@Query(value = "documentId") String documentId, @Query(value = "name") String fileName, @Query(value = "accessToken") String accessToken, @Part("file") RequestBody file);
Run Code Online (Sandbox Code Playgroud)
和
RequestBody requestBody = RequestBody.create(MediaType.parse(document.getMimeType()), file);
Call<String> call = RetrofitSingleton.getInstance(serverAddress).checkin(documentId, document.getFileName(), apiToken, requestBody);
call.enqueue(new Callback<String>() {
@Override
public void onResponse(Response<String> response, Retrofit retrofit) {
System.out.println(response.body());
}
@Override
public void onFailure(Throwable t) {
System.out.println(t.toString());
}
});
Run Code Online (Sandbox Code Playgroud)
谢谢!
编辑:
在答案之后,下载只会产生一个损坏的文件(没有@Streaming),上传也不会.当我使用上面的代码时,服务器返回400错误.将其更改为
RequestBody requestBody = RequestBody.create(MediaType.parse(document.getMimeType()), file);
MultipartBuilder multipartBuilder = new MultipartBuilder();
multipartBuilder.addFormDataPart("file", document.getFileName(), requestBody);
Call<String> call = RetrofitSingleton.getInstance(serverAddress).checkin(documentId, document.getFileName(), apiToken, multipartBuilder.build());
Run Code Online (Sandbox Code Playgroud)
,请求执行但后端似乎没有收到文件.
后端代码:
@RequestMapping(value = "/documents/checkin", method = RequestMethod.POST)
public void checkInDocument(@RequestParam String documentId,
@RequestParam String name, @RequestParam MultipartFile file,
@RequestParam String accessToken, HttpServletResponse response)
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?我能够使用Apache HttpClient从普通Java的后端:
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
builder.addBinaryBody("file", new File("E:\\temp\\test.jpg"));
HttpEntity httpEntity = builder.build();
System.out.println("HttpEntity " + EntityUtils.toString(httpEntity.));
HttpPost httpPost = new HttpPost(uri);
httpPost.setEntity(httpEntity);
Run Code Online (Sandbox Code Playgroud)
编辑v2
对于任何感兴趣的人,现在上下班工作:这些是解决方案:
服务:
@GET("documents/checkout")
public Call<ResponseBody> checkout(@Query(value = "documentUrl") String documentUrl, @Query(value = "accessToken") String accessToken, @Query(value = "readOnly") boolean readOnly);
@Multipart
@POST("documents/checkin")
public Call<String> checkin(@Query(value = "documentId") String documentId, @Query(value = "name") String fileName, @Query(value = "accessToken") String accessToken, @Part("file") RequestBody file);
Run Code Online (Sandbox Code Playgroud)
下载代码:
Call<ResponseBody> call = RetrofitSingleton.getInstance(serverAddress)
.checkout(document.getContentUrl(), apiToken, readOnly[i]);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Response<ResponseBody> response,
Retrofit retrofit) {
String fileName = document.getFileName();
try {
File path = Environment.getExternalStorageDirectory();
File file = new File(path, fileName);
FileOutputStream fileOutputStream = new FileOutputStream(file);
IOUtils.write(response.body().bytes(), fileOutputStream);
} catch (IOException e) {
Log.e(logTag, "Error while writing file!");
Log.e(logTag, e.toString());
}
}
@Override
public void onFailure(Throwable t) {
// TODO: Error handling
System.out.println(t.toString());
}
});
Run Code Online (Sandbox Code Playgroud)
上传代码:
Call<String> call = RetrofitSingleton
.getInstance(serverAddress).checkin(documentId,
document.getFileName(), apiToken,
multipartBuilder.build());
call.enqueue(new Callback<String>() {
@Override
public void onResponse(Response<String> response,
Retrofit retrofit) {
// Handle response here
}
@Override
public void onFailure(Throwable t) {
// TODO: Error handling
System.out.println("Error");
System.out.println(t.toString());
}
});
Run Code Online (Sandbox Code Playgroud)
iag*_*een 22
如需下载,您可以使用ResponseBody作为您的退货类型 -
@GET("documents/checkout")
@Streaming
public Call<ResponseBody> checkout(@Query("documentUrl") String documentUrl, @Query("accessToken") String accessToken, @Query("readOnly") boolean readOnly);
Run Code Online (Sandbox Code Playgroud)
你可以ResponseBody在你的回叫中获得输入流 -
Call<ResponseBody> call = RetrofitSingleton.getInstance(serverAddress)
.checkout(document.getContentUrl(), apiToken, readOnly[i]);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Response<ResponseBody> response,
Retrofit retrofit) {
String fileName = document.getFileName();
try {
InputStream input = response.body().byteStream();
// rest of your code
Run Code Online (Sandbox Code Playgroud)
如果您的服务器正确处理多部分消息,您的上传看起来没问题.它有效吗?如果没有,你能解释失败模式吗?您也可以通过不使其成为多部分来简化.删除@Multipart注释并转换@Path为@Body-
@POST("documents/checkin")
public Call<String> checkin(@Query("documentId") String documentId, @Query("name") String fileName, @Query("accessToken") String accessToken, @Body RequestBody file);
Run Code Online (Sandbox Code Playgroud)
小智 5
我正在使用改造 2.0.0-beta2 并且我在使用多部分请求上传图像时遇到了问题。我用这个答案解决了这个问题:https : //stackoverflow.com/a/32796626/2915075
对我来说,关键是使用标准 POST 和 MultipartRequestBody 而不是 @Multipart 注释请求。
这是我的代码:
改造服务类
@POST("photo")
Call<JsonElement> uploadPhoto(@Body RequestBody imageFile, @Query("sessionId"));
Run Code Online (Sandbox Code Playgroud)
活动中的用法,片段:
RequestBody fileBody = RequestBody.create(MediaType.parse("image/jpeg"), imageFile);
MultipartBuilder multipartBuilder = new MultipartBuilder();
multipartBuilder.addFormDataPart("photo", imageFile.getName(), fileBody);
RequestBody fileRequestBody = multipartBuilder.build();
//call
mRestClient.getRetrofitService().uploadProfilePhoto(fileRequestBody, sessionId);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
28234 次 |
| 最近记录: |