如何在 Android 应用程序中使用附加字段将照片发送到服务器?
How to send Photos to server with additional fields in Android app?
我尝试使用 Retrofit 将多张照片发送到服务器。我有这样的端点:
@Multipart
@POST("/v1/props")
Call<ModelProp> createProp(
@Header("x-auth") String token,
@Part List<MultipartBody.Part> photo
);
但我不知道如何向此 POST 方法添加附加信息:
int price;
String currency;
ArrayList<String> tags;
有人可以帮助我将这些字段添加到 POST 中吗?
编辑:
数组可能有 1000 多个元素
在 Retrofit 2 中,您可以通过以下方式向其发送带有图像的额外数据:
编辑: 根据 Ali Ghafari 的回答你也可以使用 PartMap
public interface ApiInterface {
@Multipart
@POST("/v1/props")
Call<ModelProp> createProp(@Header("x-auth") String token,
@Part List<MultipartBody.Part> photo,
@PartMap Map<String, RequestBody> map
}
你可以这样使用它:
List<MultipartBody.Part> parts = new ArrayList<>();
for (int i=0; i < upFileList.size(); i++){
parts.add(prepareFilePart("my_file["+i+"]", upFileList.get(i)));
}
Map<String, RequestBody> partMap = new HashMap<>();
partMap.put("price", createPartFromString(edtPrice.getText().toString()));
partMap.put("currency", createPartFromString(edtCurrency.getText().toString()));
partMap.put("tags", createPartFromString(new Gson().toJson(tagsArrayList));
Call<User> call = client.createProp(TokenUtils.getToken(this), partMap);
call.enqueue(new Callback<ModelProp>() {
@Override
public void onResponse(retrofit.Response<ModelProp> response, Retrofit retrofit) {
// consume response
}
@Override
public void onFailure(Throwable t) {
t.printStackTrace();
}
});
prepareFilePart
方法
private MultipartBody.Part prepareFilePart(String partName, Uri fileUri){
File file = new File(fileUri.getPath(););
RequestBody requestBody = RequestBody.create(MediaType.parse(getContentResolver().getType(fileUri)), file);
return MultipartBody.Part.createFormData(partName, file.getName(),requestBody);
}
createPartFromString
方法
public RequestBody createPartFromString(String string) {
return RequestBody.create(MultipartBody.FORM, string);
}
将您的界面更改为:
@Multipart
@POST("/v1/props")
Call<ModelProp> createProp(
@Header("x-auth") String token,
@Part List<MultipartBody.Part> photo,
@PartMap Map<String, RequestBody> map //added
);
并使用这些代码获取地图并将它们发送到 createProp
:
public Map<String, RequestBody> getMap() {
Map<String, RequestBody> partMap = new HashMap<>();
String authorS = author.getText().toString();
partMap.put("price", createPartFromString(price));
// you can put more filed to partMap
return partMap;
}
public RequestBody createPartFromString(String string) {
return RequestBody.create(MultipartBody.FORM, string);
}
选项 1: 使用多个 @Part
并正常传递参数。
@Multipart
@POST("/v1/props")
Call<ModelProp> createProp(
@Header("x-auth") String token,
@Part List<MultipartBody.Part> photo,
@Part("price") int price,
@Part("currency") String currency,
@Part("tags") List<String> tags
);
选项 2: 使用 @PartMap
并使 Map
包含您的数据。
@Multipart
@POST("/v1/props")
Call<ModelProp> createProp(
@Header("x-auth") String token,
@Part List<MultipartBody.Part> photo,
@PartMap Map<String, RequestBody> dataMap
);
并创建要传递的数据映射
RequestBody price = ...
RequestBody currency = ...
RequestBody tags = ...
HashMap<String, RequestBody> map = new HashMap<>();
map.put("price", description);
map.put("currency", place);
map.put("tags", time);
我尝试使用 Retrofit 将多张照片发送到服务器。我有这样的端点:
@Multipart
@POST("/v1/props")
Call<ModelProp> createProp(
@Header("x-auth") String token,
@Part List<MultipartBody.Part> photo
);
但我不知道如何向此 POST 方法添加附加信息:
int price;
String currency;
ArrayList<String> tags;
有人可以帮助我将这些字段添加到 POST 中吗?
编辑: 数组可能有 1000 多个元素
在 Retrofit 2 中,您可以通过以下方式向其发送带有图像的额外数据:
编辑: 根据 Ali Ghafari 的回答你也可以使用 PartMap
public interface ApiInterface {
@Multipart
@POST("/v1/props")
Call<ModelProp> createProp(@Header("x-auth") String token,
@Part List<MultipartBody.Part> photo,
@PartMap Map<String, RequestBody> map
}
你可以这样使用它:
List<MultipartBody.Part> parts = new ArrayList<>();
for (int i=0; i < upFileList.size(); i++){
parts.add(prepareFilePart("my_file["+i+"]", upFileList.get(i)));
}
Map<String, RequestBody> partMap = new HashMap<>();
partMap.put("price", createPartFromString(edtPrice.getText().toString()));
partMap.put("currency", createPartFromString(edtCurrency.getText().toString()));
partMap.put("tags", createPartFromString(new Gson().toJson(tagsArrayList));
Call<User> call = client.createProp(TokenUtils.getToken(this), partMap);
call.enqueue(new Callback<ModelProp>() {
@Override
public void onResponse(retrofit.Response<ModelProp> response, Retrofit retrofit) {
// consume response
}
@Override
public void onFailure(Throwable t) {
t.printStackTrace();
}
});
prepareFilePart
方法
private MultipartBody.Part prepareFilePart(String partName, Uri fileUri){
File file = new File(fileUri.getPath(););
RequestBody requestBody = RequestBody.create(MediaType.parse(getContentResolver().getType(fileUri)), file);
return MultipartBody.Part.createFormData(partName, file.getName(),requestBody);
}
createPartFromString
方法
public RequestBody createPartFromString(String string) {
return RequestBody.create(MultipartBody.FORM, string);
}
将您的界面更改为:
@Multipart
@POST("/v1/props")
Call<ModelProp> createProp(
@Header("x-auth") String token,
@Part List<MultipartBody.Part> photo,
@PartMap Map<String, RequestBody> map //added
);
并使用这些代码获取地图并将它们发送到 createProp
:
public Map<String, RequestBody> getMap() {
Map<String, RequestBody> partMap = new HashMap<>();
String authorS = author.getText().toString();
partMap.put("price", createPartFromString(price));
// you can put more filed to partMap
return partMap;
}
public RequestBody createPartFromString(String string) {
return RequestBody.create(MultipartBody.FORM, string);
}
选项 1: 使用多个 @Part
并正常传递参数。
@Multipart
@POST("/v1/props")
Call<ModelProp> createProp(
@Header("x-auth") String token,
@Part List<MultipartBody.Part> photo,
@Part("price") int price,
@Part("currency") String currency,
@Part("tags") List<String> tags
);
选项 2: 使用 @PartMap
并使 Map
包含您的数据。
@Multipart
@POST("/v1/props")
Call<ModelProp> createProp(
@Header("x-auth") String token,
@Part List<MultipartBody.Part> photo,
@PartMap Map<String, RequestBody> dataMap
);
并创建要传递的数据映射
RequestBody price = ...
RequestBody currency = ...
RequestBody tags = ...
HashMap<String, RequestBody> map = new HashMap<>();
map.put("price", description);
map.put("currency", place);
map.put("tags", time);