SpringBoot +Flutter + Dio + multi_image_picker +MultipartFile实现多文件上传

Flutter部分

图片上传部分UI

IconButton(
 onPressed: loadAssets,
  icon: Icon(Icons.photo),
),

加载资源

Future<void> loadAssets() async {
    List<Asset> resultList = List<Asset>();
    String error = 'No Error Dectected';
    try {
      resultList = await MultiImagePicker.pickImages(
        maxImages: 9,
        enableCamera: true,
        selectedAssets: images,
        cupertinoOptions: CupertinoOptions(takePhotoIcon: "chat"),
        materialOptions: MaterialOptions(
            actionBarColor: "#abcdef",
            actionBarTitle: "Example App",
            allViewTitle: "All Photos",
            useDetailsView: false,
            selectCircleStrokeColor: "#000000",
            startInAllView: true),
      );
    } on Exception catch (e) {
      error = e.toString();
    }
    if (!mounted) return;

    setState(() {
      images = resultList;
      _error = error;
    });
  }

点击发布按钮,将图片上传到SpringBoot

RaisedButton(
    color: Colors.green,
    child: Text(
      '发布',
      style: TextStyle(color: Colors.white, fontSize: 17),
    ),
    onPressed: uploadImageToServer
),

上传图片方法

  // 上传图片数据到Springboot后台
  uploadImageToServer() async {
    List<MultipartFile> imageList = new List<MultipartFile>();
    String url = "http://192.168.0.105:8989/users/user/testSend";
    for (Asset asset in images) {
      ByteData byteData = await asset.getByteData();
      List<int> imageData = byteData.buffer.asUint8List();
      MultipartFile multipartFile = new MultipartFile.fromBytes(
        imageData,
        filename: 'load_image',
        contentType: MediaType("image", "jpg"),
      );
      imageList.add(multipartFile);
      // print("图片数据:$imageData");
    }
    print("图片数量:${imageList.length}");

    FormData formData = FormData.fromMap({
      "multipartFiles": imageList,
      "test" : "test",
    });

    Dio dio = new Dio();
    var response = await dio.post(url, data: formData);

    //响应处理
    if (response.data["success"]) {
      print(response.data);
      Fluttertoast.showToast(
        msg: "博客上传成功,等待审核",
        gravity: ToastGravity.CENTER,
        textColor: Colors.grey,
      );
    } else {
      Fluttertoast.showToast(
        msg: "博客上传失败,请稍后再试",
        gravity: ToastGravity.CENTER,
        textColor: Colors.grey,
      );
    }
  }

在这个地方卡了挺久的,不知道什么原因,上传到SpringBoot的时候,Springboot一直显示无法接收到图片数据。在网上查了很多资料,都大同小异,没办法解决。最后想到的是用WireShark来抓包,查看上传到SpringBoot的参数是什么。看下图,注意这个参数。接下来看看SpringBoot接收参数。
在这里插入图片描述

SpringBoot部分,接收来自Flutter的图片数据

@PostMapping("testSend")
    public Map<String, Object> testSend(@RequestParam("multipartFiles[]") List<MultipartFile> multipartFiles, @RequestParam("test") String test) throws IOException {
//        List<MultipartFile> multipartFiles1 = ((MultipartHttpServletRequest) request).getFiles("multipartFiles");
        System.out.println("requestParam:"+multipartFiles.size());
        System.out.println("test:"+test);
//        System.out.println("files:" + files.length);
        for (MultipartFile multipartFile :
                multipartFiles) {
            BufferedImage image = ImageIO.read(multipartFile.getInputStream());

            String extention ="."+ multipartFile.getContentType().split("/")[1];
            UUID uuid = UUID.randomUUID();
            String path = "D:/desktop/" + uuid+ extention;
            File outputFile = new File(path);
            ImageIO.write(image,"jpg",outputFile);
        }

        Map<String, Object> map = new HashMap<>();
        map.put("success",true);
        return map;
    }

这部分需要特别注意的就是这个注解@RequestParam(“multipartFiles[]”),我们看之前在Flutter 的FormData里面设置的是multipartFiles,而这里必须设置为multipartFiles[],否则无法获取到传递过来的图片数据

在此之前,为了排查是前端错误还是后端错误,用过PostMan上传图片数据,显示是能上传成功的,所以就认为可能错误是出现在Flutter那里(实际上不是,就是在SpringBoot!!!)。

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值