【问题标题】:How to send Photos to server with additional fields in Android app?如何在 Android 应用中使用附加字段将照片发送到服务器?
【发布时间】:2019-06-23 01:49:06
【问题描述】:

我尝试使用 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 多个元素

【问题讨论】:

  • 您可以在查询字符串中添加其他信息
  • 如何将数组添加到查询字符串?有办法吗?
  • 在制作网址时,可以在其中添加查询参数。在服务器上,您必须处理这些参数。 HttpUrl url = originalHttpUrl.newBuilder() .addQueryParameter("param1", "param1_value") .build();
  • 感谢您的建议,但如果数组中有 1000 个项目,则将其添加到查询字符串中不是一个好主意

标签: android retrofit2 multipartform-data


【解决方案1】:

在 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);
    }

【讨论】:

  • 看起来是真的,会用代码检查它并标记答案。谢谢!
  • 从哪里可以得到 new File(getPath(fileUri)) 中的 getPath() 方法?
  • fileUri.getPath() - 给出错误 onFailure: /external/images/media/63927 (没有这样的文件或目录)
【解决方案2】:

把你的界面改成这样:

@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);
    }

【讨论】:

  • 如何添加一个数组?
【解决方案3】:

选项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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-10
    • 1970-01-01
    • 1970-01-01
    • 2015-04-20
    • 1970-01-01
    • 2018-12-20
    • 1970-01-01
    • 2015-06-01
    相关资源
    最近更新 更多