上传单个图像似乎对改造2没有问题。
然而, 我无法弄清楚如何同时上传2张图片。
如果遵循文档: http://square.github.io/retrofit/2.x/retrofit/retrofit2/http/PartMap.html
File file = new File(path, "theimage");
File file2 = new File(path2, "theimage");
RequestBody requestBody = RequestBody.create(MediaType.parse("image/png"), file);
RequestBody requestBody2 = RequestBody.create(MediaType.parse("image/png"), file2);
Map<String, RequestBody> params = new HashMap<>();
params.put("image2", requestBody2 );
Call<ResponseBody> call = service.upload(requestBody, params);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Response<ResponseBody> response, Retrofit retrofit) {
Log.v("Upload", "success");
}
接口:
public interface FileUploadService {
@Multipart
@POST("/upload")
Call<ResponseBody> upload(
//@Part("image_logo\"; filename=\"image.png\" ") RequestBody file,
@Part("file") RequestBody file,
@PartMap Map<String, RequestBody> params
// @Part("description") String description
);
这给了'上传:成功',但在服务器端我得到了胡言乱语:
CONTENT_TYPE:multipart / form-data; 边界= 50fbfeb3-3abc-4f15-B130-cdcb7e3a0e4f
CONTENT POST:Array( [file] =&gt; PNGIHDRL alotofbinarygibberish .... ...剪断 [file2] =&gt; PNG IHDR L更多二元胡言乱语......
有人能指出我正确的方向吗?
单个上传确实有效,所以不是问题,我正在尝试上传2个或更多图片。
如果我将其更改为:
HashMap<String, RequestBody> partMap = new HashMap<String, RequestBody>();
partMap.put("file\"; filename=\"" + file.getName(), requestBody);
partMap.put("file\"; filename=\"" + file2.getName(), requestBody);
Call<ResponseBody> call = service.upload(partMap);
@Multipart
@POST("/upload")
Call<ResponseBody> upload(
@PartMap() Map<String, RequestBody> partMap,
我没有乱码,但只上传了第二张图片......!?
我尝试了这个Retrofit(2.0 beta2) Multipart file upload doesn't work解决方案,但是得到了@body不能用于multipart的错误: Java.lang.IllegalArgumentException:@Body参数不能与表单或多部分编码一起使用。 (参数#1)
for (String key : keys) {
Bitmap bm = selectedImages.get(key);
File f = new File(saveToInternalStorage(bm, key), key);
if (f.exists()) {
buildernew.addFormDataPart(key, key + ".png", RequestBody.create(MEDIA_TYPE, f));
}
}
RequestBody requestBody = buildernew.build();
-
Call<ResponseBody> upload(
@Body RequestBody requestBody
答案 0 :(得分:7)
final MediaType MEDIA_TYPE=MediaType.parse("image/png");
HashMap<String,RequestBody> map=new HashMap<>(selectedImages.size());
RequestBody file=null;
File f=null;
Set<String> keys = selectedImages.keySet();
for (String key : keys) {
try {
Bitmap bitmap = selectedImages.get(key);
f = new File(saveToInternalStorage(bitmap, key), key);
FileOutputStream fos = new FileOutputStream(f);
if(bitmap!=null){
bitmap.compress(Bitmap.CompressFormat.PNG, 0 , fos);
fos.flush();
fos.close();
}
} catch (Exception e) {
e.printStackTrace();
return;
}
file=RequestBody.create(MEDIA_TYPE, f);
map.put(""+key+"\"; filename=\""+key+".jpg",file);
Log.i("##MYLOG###", "### MAP PUT:" + key + " filename:"+key+".jpg file:" + file.toString() +" type:"+ file.contentType() );
file=null;
f = null;
}
-
Call<ResponseBody> upload(
@PartMap() Map<String,RequestBody> mapFileAndName //for sending multiple images
-
注意:在使用httpClient.interceptors()进行调试时,我只看到一次上传,但在检查端点本身以查看它实际得到的内容时,它就会获得多次上传!
答案 1 :(得分:2)
我可能会迟到,但我的回答可能有助于未来的访客
我要求用户选择这样的多个图像:
int PICK_IMAGE_MULTIPLE = 1;
Intent intent = new Intent();
intent.setType("image/*");
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_MULTIPLE);
然后在onActivityResult()
我这样做:
ArrayList<String> filePaths;
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE_MULTIPLE) {
if (data != null) {
filePaths=new ArrayList<>();
// If data.getData() == null means multiple images selected, else single image selected.
if (data.getData() == null) {
ClipData clipData = data.getClipData();
if (clipData != null) {
for (int i = 0; i < clipData.getItemCount(); i++) {
ClipData.Item item = clipData.getItemAt(i);
Uri uri = item.getUri();
filePaths.add(FileUtils.getPath(Activity.this, uri));
}
}
} else {
filePaths.add(FileUtils.getPath(Activity.this,data.getData()));
}
sendToServer();
}
}
}
您可以从this Github link
获取FileUtils
课程
我的sendToServer()
方法如下所示:
private void sendToServer() {
if(filePaths!=null) {
ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);
MediaType MEDIA_TYPE_IMG = MediaType.parse("image/jpeg");
MultipartBody.Builder builder=new MultipartBody.Builder();
builder.setType(MultipartBody.FORM);
RequestBody requestBody;
try {
for (int i = 0; i < filePaths.size(); i++) {
File file = new File(filePaths.get(i));
requestBody=RequestBody.create(MEDIA_TYPE_IMG,file);
builder.addFormDataPart("photo"+i,file.getName(),requestBody);
}
RequestBody finalRequestBody=builder.build();
Call<YourResponse> call=apiService.addEvent(finalRequestBody);
call.enqueue(new Callback<YourResponse>() {
@Override
public void onResponse(Call<YourResponse> call, Response<YourResponse> response) {
// process response
}
@Override
public void onFailure(Call<YourResponse> call, Throwable t) {
t.printStackTrace();
t.getCause();
}
});
}catch (Exception e){
e.printStackTrace();
}
}
}
最后,我的Retrofit端点如下所示:
@POST("event/add")
Call<YourResponse> addEvent(@Body RequestBody body);
请注意,YourResponse
可以是您处理回复的自定义模型类,或者您也可以使用原始Response
类,而不想制作模型类。
希望这有助于新访客。
答案 2 :(得分:1)
试试这个
对于API:
//Multiple Images
@Multipart
@POST(HttpConstants.FILEMULTIPLEUPLOAD)
Call<Result>uploadMultipleImage(@Part MultipartBody.Part files1,@Part MultipartBody.Part files2, @Query("total_images") int total, @Query("stdID") int stdID);
客户端
public class RaytaServiceClass {
public RaytaServiceClass() {
}
private static Retrofit getRetroClient(){
Gson gson = new GsonBuilder()
.setLenient()
.create();
return new Retrofit.Builder()
.baseUrl(HttpConstants.baseUrl)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
}
public static RaytaApi getApiService(){
return getRetroClient().create(RaytaApi.class);
}
}
电话
RaytaApi service= RaytaServiceClass.getApiService();
File file1 = new File(selectedPath1);
File file2 = new File(selectedPath2);
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file1);
RequestBody requestFile2 = RequestBody.create(MediaType.parse("multipart/form-data"), file2);
MultipartBody.Part body =
MultipartBody.Part.createFormData("uploaded_file", file1.getName(), requestFile);
MultipartBody.Part body2 =
MultipartBody.Part.createFormData("uploaded_file", file2.getName(), requestFile2);
Call<Result> resultCall=service.uploadMultipleImage(body,body2,2,1);
Log.v("@@@@WWE","REquest "+resultCall.toString());
Log.v("@@@WWE","Retrofit Request Method = "+resultCall.request().method());
Log.v("@@@WWE","Retrofit Request Body = "+resultCall.request().body());
Log.v("@@@WWE","Retrofit Request Url = "+resultCall.request().url());
final Result[] result = {new Result()};
resultCall.enqueue(new Callback<Result>() {
@Override
public void onResponse(Call<Result> call, Response<Result> response) {
progressDialog.dismiss();
Log.v("@@@WWE","Respnse");
result[0] =response.body();
Log.v("@@@WWE","Response Result "+result[0].getResult());
if(response.isSuccessful()){
Toast.makeText(UploadMultipleImageActivity.this,"Sucess",Toast.LENGTH_SHORT).show();
Toast.makeText(UploadMultipleImageActivity.this,"Press Refresh Button",Toast.LENGTH_LONG).show();
supportFinishAfterTransition();
}
}
@Override
public void onFailure(Call<Result> call, Throwable t) {
progressDialog.dismiss();
Log.v("@@@WWE","Failure ");
Log.v("@@@WWE","MEssage "+t.getMessage());
}
});