之前发过一篇上传多张图片的博客,那个是自己实现的,但是是一张一张上传最后页面上显示出来所有上传的图片,这篇文章介绍一下一次性选择多张图片并上传
首先引入依赖:multi_image_picker,这个插件可以选择多张图片,插件地址https://pub.flutter-io.cn/packages/multi_image_picker
然后画个小页面
import 'package:flutter/material.dart'; import 'dart:io'; //ByteData这里需要引入dart:typed_data文件,引入service.dart的话app里可以检索到文件个数,但是传递到后台一直是null,时间紧迫我也没抓包看是咋回事儿先这么用吧 import 'dart:typed_data'; import 'package:dio/dio.dart'; //MediaType用 import 'package:http_parser/http_parser.dart'; import 'package:multi_image_picker/multi_image_picker.dart'; class TestPage extends StatefulWidget { final arguments; TestPage({Key key, this.arguments}) : super(key : key); _TestPageState createState() => _TestPageState(this.arguments); } class _TestPageState extends State<TestPage> { final arguments; _TestPageState(this.arguments); //上传图片用 ScrollController _imgController = new ScrollController(); List<Asset> _img = new List<Asset>(); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( leading: InkWell( child: Icon(Icons.keyboard_return), onTap: (){ Navigator.pop(context); }, ), title: Text("上传照片"), ), body: Padding( padding: EdgeInsets.all(10), child: Column( children: [ Row( children: <Widget>[ this._img == null ? Expanded( flex: 1, child: Text(""), ) : Expanded( flex: 1, child: Container( width: double.infinity, height: 50, child: ListView.builder( controller: _imgController, shrinkWrap: true, scrollDirection: Axis.horizontal, itemCount: this._img.length, itemBuilder: (context, index){ return Container( width: 50, height: 50, margin: EdgeInsets.only(right: 10), decoration: BoxDecoration( borderRadius: BorderRadius.circular(4.0), border: Border.all( style: BorderStyle.solid, color: Colors.black26, ) ), child: AssetThumb( asset: this._img[index], width: 50, height: 50, ), ); }, ), ), ), InkWell( child: Container( width: 50, height: 50, margin: EdgeInsets.only(right: 10), decoration: BoxDecoration( borderRadius: BorderRadius.circular(4.0), border: Border.all( style: BorderStyle.solid, color: Colors.black26, ) ), child: Center( child: Icon(Icons.camera_alt), ), ), onTap: _openGallerySystem , ) ], ), Container( width: double.infinity, height: 80, child: RaisedButton( color: Colors.blue, child: Text( "提交", style: TextStyle(color: Colors.white), ), onPressed: () { _submitData(); }, ), ), ], ) ), ); } //选择文件上传 void _openGallerySystem () async { List<Asset> resultList = List<Asset>(); resultList = await MultiImagePicker.pickImages( //最多选择几张照片 maxImages: 9, //是否可以拍照 enableCamera: true, selectedAssets: _img, materialOptions:MaterialOptions( startInAllView:true, allViewTitle:'所有照片', actionBarColor:'#2196F3', //未选择图片时提示 textOnNothingSelected:'没有选择照片', //选择图片超过限制弹出提示 selectionLimitReachedText: "最多选择9张照片" ), ); if (!mounted) return; setState(() { _img = resultList; }); } //提交数据 void _submitData () async { //处理图片 List<MultipartFile> imageList = new List<MultipartFile>(); for (Asset asset in _img) { //将图片转为二进制数据 ByteData byteData = await asset.getByteData(); List<int> imageData = byteData.buffer.asUint8List(); MultipartFile multipartFile = new MultipartFile.fromBytes( imageData, //这个字段要有,否则后端接收为null filename: 'load_image', //请求contentType,设置一下,不设置的话默认的是application/octet/stream,后台可以接收到数据,但上传后是.octet-stream文件 contentType: MediaType("image", "jpg"), ); imageList.add(multipartFile); } FormData formData = new FormData.fromMap({ //后端要用multipartFiles接收参数,否则为null "multipartFiles" : imageList }); var res = await Dio().post("你的URL", data: formData); //后面随意发挥 } }选择图片截图:这个插件选择图片后还有个加载过程,挺好的(按钮有点丑,凑合看吧,哈哈哈)
后端方法:SpringBoot
@RequestMapping(value = "xxx", method = RequestMethod.POST) //一定要有这个注解@RequestParam("multipartFiles[]"),否则接收不到参数 public String testupload (@RequestParam("multipartFiles[]") List<MultipartFile> multipartFiles) throws IOException { if (multipartFiles.size() > 0) { for (MultipartFile multipartFile : multipartFiles) { //上传图片 BufferedImage image = ImageIO.read(multipartFile.getInputStream()); System.out.println(image); String extention ="."+ multipartFile.getContentType().split("/")[1]; UUID uuid = UUID.randomUUID(); String path = "D:/haha/" + uuid+ extention; File outputFile = new File(path); ImageIO.write(image, "jpg", outputFile); } } return "ok"; }上传后截图:
中间还有个小波折,第一次测试程序的时候程序报了个错:The multi-part request contained parameter data (excluding uploaded files) that exceeded the limit for maxPostSize set on the associated connector
开始以为是图片的过大,但是我已经在项目中设置了
spring.servlet.multipart.max-file-size = 100MB
spring.servlet.multipart.max-request-size=100MB
感觉不应该是图片尺寸的问题,
后来网上找了办法说是springboot中的内置tomcat服务器限定了Httppost的最大size
解决办法:在properties中添加如下配置,修改该内置服务器的对HttpPost数据的大小
server.max-http-header-size=102400000
server.tomcat.max-http-post-size=102400000
参考链接:https://blog.csdn.net/Draught_Bear/article/details/105601473