改造 2 文件 down/upload
Retrofit 2 file down/upload
我正在尝试 down/upload 一个带有 retrofit 2 的文件,但找不到任何关于如何操作的教程示例。
我的下载密码是:
@GET("documents/checkout")
public Call<File> checkout(@Query(value = "documentUrl") String documentUrl, @Query(value = "accessToken") String accessToken, @Query(value = "readOnly") boolean readOnly);
和
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());
}
});
我试过呼叫和呼叫,但似乎没有任何效果。
server-side 代码在正确设置 headers 和 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);
和
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());
}
});
谢谢!
编辑:
回答后,下载只会产生损坏的文件(没有@Streaming),上传也不会。当我使用上面的代码时,服务器 returns 出现 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());
,请求执行了,但是后端似乎没有收到文件。
后端代码:
@RequestMapping(value = "/documents/checkin", method = RequestMethod.POST)
public void checkInDocument(@RequestParam String documentId,
@RequestParam String name, @RequestParam MultipartFile file,
@RequestParam String accessToken, HttpServletResponse response)
我做错了什么?我能够使用普通 Java 的后端和 Apache HttpClient:
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);
编辑 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);
下载码:
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());
}
});
上传代码:
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());
}
});
对于下载,您可以使用 ResponseBody
作为您的 return 类型 --
@GET("documents/checkout")
@Streaming
public Call<ResponseBody> checkout(@Query("documentUrl") String documentUrl, @Query("accessToken") String accessToken, @Query("readOnly") boolean readOnly);
并且您可以在回调中获得 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
如果您的服务器正确处理了多部分消息,您的上传乍一看没问题。它在工作吗?如果不是,你能解释一下故障模式吗?您也可以通过不使其成为多部分来简化。删除@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);
我使用的是改造 2.0.0-beta2,使用多部分请求上传图片时遇到问题。我用这个答案解决了它:
我的关键是使用标准 POST 和 MultipartRequestBody 而不是 @Multipart 带注释的请求。
这是我的代码:
改装服务class
@POST("photo")
Call<JsonElement> uploadPhoto(@Body RequestBody imageFile, @Query("sessionId"));
用法来自 activity,片段:
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);
我有同样的问题,我找到了上传文件的解决方案,在此处描述
我也遇到了这个问题,这就是我尝试解决问题的方法 (RETROFIT 2)
//1. What We Need From Server ( upload.php Script )
public class FromServer {
String result;
}
//2. Which Interface To Communicate Our upload.php Script?
public interface ServerAPI {
@Multipart
@POST("upload.php")//Our Destination PHP Script
Call<List<FromServer>> upload(
@Part("file_name") String file_name,
@Part("file") RequestBody description);
Retrofit retrofit =
new Retrofit.Builder()
.baseUrl("http://192.168.43.135/retro/") // REMEMBER TO END with /
.addConverterFactory(GsonConverterFactory.create())
.build();
}
//3. How To Upload
private void upload(){
ServerAPI api = ServerAPI.retrofit.create(ServerAPI.class);
File from_phone = FileUtils.getFile(Environment.getExternalStorageDirectory()+"/aa.jpg"); //org.apache.commons.io.FileUtils
RequestBody to_server = RequestBody.create(MediaType.parse("multipart/form-data"), from_phone);
api.upload(from_phone.getName(),to_server).enqueue(new Callback<List<FromServer>>() {
@Override
public void onResponse(Call<List<FromServer>> call, Response<List<FromServer>> response) {
Toast.makeText(MainActivity.this, response.body().get(0).result, Toast.LENGTH_SHORT).show();
}
@Override
public void onFailure(Call<List<FromServer>> call, Throwable t) { }
});
}
//4. upload.php
<?php
$pic = $_POST['file_name'];
$pic = str_replace("\"", "", $pic); //REMOVE " from file name
if(file_exists($pic)){unlink($pic);}
$f = fopen($pic, "w");
fwrite($f,$_POST['file']);
fclose($f);
$arr[] = array("result"=>"Done");
print(json_encode($arr));
?>
Image Download using Retrofit 2.0
可以参考教程
图片下载暂时可以参考以下功能:
void getRetrofitImage() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitImageAPI service = retrofit.create(RetrofitImageAPI.class);
Call<ResponseBody> call = service.getImageDetails();
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Response<ResponseBody> response, Retrofit retrofit) {
try {
Log.d("onResponse", "Response came from server");
boolean FileDownloaded = DownloadImage(response.body());
Log.d("onResponse", "Image is downloaded and saved ? " + FileDownloaded);
} catch (Exception e) {
Log.d("onResponse", "There is an error");
e.printStackTrace();
}
}
@Override
public void onFailure(Throwable t) {
Log.d("onFailure", t.toString());
}
});
}
以下是使用Retrofit 2.0的文件处理部分图片下载
private boolean DownloadImage(ResponseBody body) {
try {
Log.d("DownloadImage", "Reading and writing file");
InputStream in = null;
FileOutputStream out = null;
try {
in = body.byteStream();
out = new FileOutputStream(getExternalFilesDir(null) + File.separator + "AndroidTutorialPoint.jpg");
int c;
while ((c = in.read()) != -1) {
out.write(c);
}
}
catch (IOException e) {
Log.d("DownloadImage",e.toString());
return false;
}
finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
int width, height;
ImageView image = (ImageView) findViewById(R.id.imageViewId);
Bitmap bMap = BitmapFactory.decodeFile(getExternalFilesDir(null) + File.separator + "AndroidTutorialPoint.jpg");
width = 2*bMap.getWidth();
height = 6*bMap.getHeight();
Bitmap bMap2 = Bitmap.createScaledBitmap(bMap, width, height, false);
image.setImageBitmap(bMap2);
return true;
} catch (IOException e) {
Log.d("DownloadImage",e.toString());
return false;
}
}
希望对您有所帮助。祝一切顺利。快乐编码:)
我正在尝试 down/upload 一个带有 retrofit 2 的文件,但找不到任何关于如何操作的教程示例。 我的下载密码是:
@GET("documents/checkout")
public Call<File> checkout(@Query(value = "documentUrl") String documentUrl, @Query(value = "accessToken") String accessToken, @Query(value = "readOnly") boolean readOnly);
和
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());
}
});
我试过呼叫和呼叫,但似乎没有任何效果。
server-side 代码在正确设置 headers 和 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);
和
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());
}
});
谢谢!
编辑:
回答后,下载只会产生损坏的文件(没有@Streaming),上传也不会。当我使用上面的代码时,服务器 returns 出现 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());
,请求执行了,但是后端似乎没有收到文件。
后端代码:
@RequestMapping(value = "/documents/checkin", method = RequestMethod.POST)
public void checkInDocument(@RequestParam String documentId,
@RequestParam String name, @RequestParam MultipartFile file,
@RequestParam String accessToken, HttpServletResponse response)
我做错了什么?我能够使用普通 Java 的后端和 Apache HttpClient:
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);
编辑 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);
下载码:
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());
}
});
上传代码:
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());
}
});
对于下载,您可以使用 ResponseBody
作为您的 return 类型 --
@GET("documents/checkout")
@Streaming
public Call<ResponseBody> checkout(@Query("documentUrl") String documentUrl, @Query("accessToken") String accessToken, @Query("readOnly") boolean readOnly);
并且您可以在回调中获得 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
如果您的服务器正确处理了多部分消息,您的上传乍一看没问题。它在工作吗?如果不是,你能解释一下故障模式吗?您也可以通过不使其成为多部分来简化。删除@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);
我使用的是改造 2.0.0-beta2,使用多部分请求上传图片时遇到问题。我用这个答案解决了它:
我的关键是使用标准 POST 和 MultipartRequestBody 而不是 @Multipart 带注释的请求。
这是我的代码:
改装服务class
@POST("photo")
Call<JsonElement> uploadPhoto(@Body RequestBody imageFile, @Query("sessionId"));
用法来自 activity,片段:
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);
我有同样的问题,我找到了上传文件的解决方案,在此处描述
我也遇到了这个问题,这就是我尝试解决问题的方法 (RETROFIT 2)
//1. What We Need From Server ( upload.php Script )
public class FromServer {
String result;
}
//2. Which Interface To Communicate Our upload.php Script?
public interface ServerAPI {
@Multipart
@POST("upload.php")//Our Destination PHP Script
Call<List<FromServer>> upload(
@Part("file_name") String file_name,
@Part("file") RequestBody description);
Retrofit retrofit =
new Retrofit.Builder()
.baseUrl("http://192.168.43.135/retro/") // REMEMBER TO END with /
.addConverterFactory(GsonConverterFactory.create())
.build();
}
//3. How To Upload
private void upload(){
ServerAPI api = ServerAPI.retrofit.create(ServerAPI.class);
File from_phone = FileUtils.getFile(Environment.getExternalStorageDirectory()+"/aa.jpg"); //org.apache.commons.io.FileUtils
RequestBody to_server = RequestBody.create(MediaType.parse("multipart/form-data"), from_phone);
api.upload(from_phone.getName(),to_server).enqueue(new Callback<List<FromServer>>() {
@Override
public void onResponse(Call<List<FromServer>> call, Response<List<FromServer>> response) {
Toast.makeText(MainActivity.this, response.body().get(0).result, Toast.LENGTH_SHORT).show();
}
@Override
public void onFailure(Call<List<FromServer>> call, Throwable t) { }
});
}
//4. upload.php
<?php
$pic = $_POST['file_name'];
$pic = str_replace("\"", "", $pic); //REMOVE " from file name
if(file_exists($pic)){unlink($pic);}
$f = fopen($pic, "w");
fwrite($f,$_POST['file']);
fclose($f);
$arr[] = array("result"=>"Done");
print(json_encode($arr));
?>
Image Download using Retrofit 2.0
可以参考教程图片下载暂时可以参考以下功能:
void getRetrofitImage() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitImageAPI service = retrofit.create(RetrofitImageAPI.class);
Call<ResponseBody> call = service.getImageDetails();
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Response<ResponseBody> response, Retrofit retrofit) {
try {
Log.d("onResponse", "Response came from server");
boolean FileDownloaded = DownloadImage(response.body());
Log.d("onResponse", "Image is downloaded and saved ? " + FileDownloaded);
} catch (Exception e) {
Log.d("onResponse", "There is an error");
e.printStackTrace();
}
}
@Override
public void onFailure(Throwable t) {
Log.d("onFailure", t.toString());
}
});
}
以下是使用Retrofit 2.0的文件处理部分图片下载
private boolean DownloadImage(ResponseBody body) {
try {
Log.d("DownloadImage", "Reading and writing file");
InputStream in = null;
FileOutputStream out = null;
try {
in = body.byteStream();
out = new FileOutputStream(getExternalFilesDir(null) + File.separator + "AndroidTutorialPoint.jpg");
int c;
while ((c = in.read()) != -1) {
out.write(c);
}
}
catch (IOException e) {
Log.d("DownloadImage",e.toString());
return false;
}
finally {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}
int width, height;
ImageView image = (ImageView) findViewById(R.id.imageViewId);
Bitmap bMap = BitmapFactory.decodeFile(getExternalFilesDir(null) + File.separator + "AndroidTutorialPoint.jpg");
width = 2*bMap.getWidth();
height = 6*bMap.getHeight();
Bitmap bMap2 = Bitmap.createScaledBitmap(bMap, width, height, false);
image.setImageBitmap(bMap2);
return true;
} catch (IOException e) {
Log.d("DownloadImage",e.toString());
return false;
}
}
希望对您有所帮助。祝一切顺利。快乐编码:)