【问题标题】:How to send file using Chopper?如何使用 Chopper 发送文件?
【发布时间】:2020-05-16 05:49:56
【问题描述】:

在我的 kotlin 项目中,我使用 retrofit,它运行良好。

suspend fun createPlan(
    context: Context?,
    name: String,
    file: File?
): ABC? {

    val fileSignImage = file?.let {
        MultipartBody.Part.createFormData(
            "image",
            it.getName(),
            RequestBody.create("image/*".toMediaTypeOrNull(), it)
        )
    }

    return RetrofitFactory.apiCall(context) {
        RetrofitFactory.makeRetrofitService().createPlan(
            name.toRequestBody("text/plain".toMediaTypeOrNull()),
            fileSignImage
        )
    }} 

改造服务

@Multipart
@POST("create_plan")
fun createPlan(
    @Part("name") name: RequestBody,
    @Part image: MultipartBody.Part?
): Deferred<Response<WebApiResponse.ABCs>>

如果我想使用Chopper,正确的方法是什么?

这是我尝试过的

Future<Response> createPlan(
      BuildContext context, String name,String path) async {
    Response response;
    try {
      response = await _service.createPlan(
           name,path);
      return response;
    } catch (e) {
      rethrow;
    }
  }

服务

@Post(path: "create_plan")
@multipart
Future<Response> createPlan(
@Field('name') String name,@PartFile('image') String imagePath);

如何将 imagePath 转换为文件,以便使用 Chopper 将其作为文件传递给服务器?

有人吗?

【问题讨论】:

  • 你已经显示了代码sn-ps,但是你没有提到问题是什么,所以没人能回答。您是否尝试过运行该代码?你有任何例外吗?请求没有发送吗?服务器没有收到请求吗?请求不包含您的期望吗?什么问题???
  • @Ovidiu 我想将文件而不是字符串传递给服务器。
  • 你的服务器是在接收一个字符串,还是你只是假设你正在发送一个字符串?在尝试运行该代码 sn-p 时,您再次没有描述问题是什么(至少没有任何技术证明,例如异常或奇怪的请求正文)。您正在使用一种受支持的数据类型:github.com/lejard-h/chopper/blob/master/chopper/lib/src/… 什么不起作用???
  • @Ovidiu 服务器端不应接受String。在我的 kotlin 代码中,我实际上将 MultipartBody.Part 传递给服务器,一切正常。但在颤抖中,它失败了。我不能告诉你错误是什么,因为错误是从服务器端返回的。我猜是因为我将其传递为String,而不是MultipartBody.Part
  • 你的意思是你不能告诉错误是什么,因为它是由服务器返回的?以及您如何期望任何人在不指定错误的情况下帮助您?

标签: kotlin flutter dart retrofit2 chopper


【解决方案1】:

我设法使用 http 而不是 Chopper 上传文件。

   Future<http.Response> createPlan(String name, String path) async {
        var request = http.MultipartRequest(
            "POST",
            Uri.parse(
                "http://xxx"));

        request.fields['name'] = name;
        request.files.add(await http.MultipartFile.fromPath(
          'image',
          path,
        ));

        try {
          var streamedResponse = await request.send();
          var response = http.Response.fromStream(streamedResponse);
          return response;
        } catch (e) {
         rethrow;
        }
      }

【讨论】:

    【解决方案2】:

    查看Chopper的文档,PartFile注解支持三种数据类型:

    • List&lt;int&gt;
    • String(文件路径)
    • MultipartFile(来自包:http)

    您目前正在使用String,但由于未知原因,它不适合您。第一个选项可能是最直接的,但第三个选项与您目前在 Retrofit 中的选项最相似,所以我们可以尝试一下。

    import 'package:http/http.dart';
    
    ...
    
    Future<Response> createPlan(BuildContext context, String name, String path) async {
      Response response;
      try {
        final bytes = (await File(path).readAsBytes()).toList();
        final file = MultipartFile.fromBytes('image', bytes);
        response = await _service.createPlan(
          name,
          file,
        );
        return response;
      } catch (e) {
        rethrow;
      }
    }
    

    服务

    @Post(path: "create_plan")
    @multipart
    Future<Response> createPlan(
      @Field('name') String name,
      @PartFile('image') MultipartFile image,
    );
    

    【讨论】:

    • The method 'readAsBytes' isn't defined for the class 'File'. Try correcting the name to the name of an existing method, or defining a method named 'readAsBytes'.
    • @Hoo 你导入dart:io了吗?
    • 好的,我现在在导入后得到这个。 Too many positional arguments: 0 expected, but 1 found. Try removing the extra arguments.
    • @Hoo 啊,这些天我在 C# 和 JS 上花了太多时间,我一直忘记 Dart 的 File 方法不是静态的。请参阅该行的编辑。
    • 仍然无法正常工作。服务器端想要MultipartBody.Part 而不是MultipartFile
    猜你喜欢
    • 2021-01-02
    • 2015-10-23
    • 2014-02-03
    • 2019-06-09
    • 1970-01-01
    • 1970-01-01
    • 2013-03-24
    • 2019-09-16
    • 1970-01-01
    相关资源
    最近更新 更多