• ServletFileUpload获取上传的多个文件和数据


    引言

    最近工作上做的需求是整合两个项目的文件,将另外一个使用的servlet完成的两个接口的项目整合到springboot项目中。(文件上传和文件下载接口)

    在整合的过程中遇到了许多问题,比如:spring中默认使用的MultipartFile来进行文件的上传,但是那个servlet的项目中使用的是ServletFileUpload来进行的文件上传,这就导致了如果使用springboot的方式写controller完成需求的话,无法从ServletFileUpload中取到相关数据(springboot的MultipartFile不允许关闭,因为有其它接口使用的MultipartFile)。

    查询了许多资料后,感觉有一个挺正确的答案,就是重写spring默认的MultipartFileisMultipart接口,但是不知道为什么,配置到项目中还是不行。

    后来经过leader的指导,发现在springboot中使用servlet的方式去完成的话是可以取到文件数据的,然后我就开始使用servlet去完成需求,但是完成的过程中坑越来越多。

    • 第一个遇到的坑就是:在servlet中使用req.getParameter()获取不到值!!!,经过查询后,发现是因为表单是以form-data提交的所以才取不到,那为什么我们平时在spring或springboot中就可以取到呢?因为spring内部跟我们做了很多操作,于是我就参考着网上的方法去调用spring内部的工具进行处理,处理完成后我发现普通表单提交的数据是可以取到了,但是文件数据又全丢失了!!害,这个时候不得不又开启谷歌大法,最后的解决方案就是通过代码展示中的操作,原因是因为form-data提交上来的数据是另外一种格式,我们需要以数据流的方式去获取它,然后就可以将它里面的数据取出来了。到这里,第一个坑终于结束,但是第二个坑就此开始了

    • 在第一个坑踩完后,本以为之后就可以顺风顺水,没想到第二个坑就来了,这次出现的问题是,在执行文件写出的时候报错

      Method threw 'org.apache.commons.fileupload.MultipartStream$MalformedStreamException' exception.
      
      • 1

      具体错误就发生在文件写入的时候,这个问题我谷歌搜了好久,得到的答案就是:1.文件的边界格式读取有问题 2.可能电脑又加密软件啥的

      后来实在解决不了,我就直接把这个文件写出给跳过了,然后第三个坑就开始了

    • 第三个坑的错误与第二个坑如出一辙,都是文件方面的问题,在使用原项目的方式去遍历读取的时候,遍历到结束时会出现报错

      org.apache.commons.fileupload.MultipartStream$MalformedStreamException: Stream ended unexpectedly
      
      • 1

      这个错误我当时也没有去解决,实在解决不了

    后来,我想着有没有可能是它本来写的代码就有问题,于是,我就把他的ServletFileUpload获取文件数据的方式去进行了修改,修改后发现,坑2和坑3都没了!!!后来经过简单是测试,调整,终于将需求完成。

    代码展示

    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置缓冲区大小
        DiskFileItemFactory factory = new DiskFileItemFactory();
        //创建一个上床据
        ServletFileUpload upload = new ServletFileUpload(factory);
        //设置上传文件大小
        upload.setFileSizeMax(1024*1024*50);
        upload.setSizeMax(1024*1024*50);
        //解决上传文件中文名称乱码
        upload.setHeaderEncoding("UTF-8");
        //定义一个map接收普通表单对象
        Map<String, String> param = new HashMap<String, String>();
        //定义一个List接受文件数据
        List<FileItem> iter = new ArrayList<>();
    
        //解析request对象,得到所有上传项,每一个fileItem相当于一个上传项(包括普通表单数据和文件数据)
        List<FileItem> items = upload.parseRequest(req);
    
        try {
            //遍历解析出来的对象
            for (FileItem fileItem : items) {
                if (fileItem.isFormField()) {//如果是普通输入项数据
                    param.put(fileItem.getFieldName(), fileItem.getString("utf-8"));
                }else {//如果是上传的文件数据
                    iter.add(fileItem);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        //将我们获取到的普通表单值赋值出来(之前我们存在了map里面)
        String processID =  param.get("ProcessID");
        String serverPath =  param.get("ServerPath");
        String dateIn =  param.get("dateIn");
        String modifiedBy =  param.get("modifiedBy");
        String fileType =  param.get("fileType");
        
        //如果请求中存在文件
        //如果不存在文件那么iter.get(0).getName()
        if(!StringUtils.isEmpty(iter.get(0).getName())){
            
            //开始文件操作
            //创建文件数据集合的迭代器
            Iterator<FileItem> iterator = iter.iterator();
    
            //如果上传了多个文件,则会执行多次
            while(iterator.hasNext()){
                //获取迭代器中数据(存储的是我们传上来的文件数据)
                FileItem fileItem = iterator.next();
                //获取文件输入流
                InputStream input = fileItem.getInputStream();
                //获取文件名
                fileName = fileItem.getName();
    
                //后面的就是可以对文件输入流进行相关操作了
                ... ...
                //以下省略
    
            }
            
        }
       
        
        
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65

    总结

    • 在优化别人代码的时候,别人代码不一定正确
    • 在写代码的时候要有写注释的好习惯
    • 解决完bug后需要即使进行总结
    • 问题解决不了不要着急,慢慢来
  • 相关阅读:
    LeetCode每日一题(321. Create Maximum Number)
    毕业设计-机器视觉深度学习的视频去水印算法
    python协程和任务
    后端实现大文件分片上传
    top100-贪心算法
    全流程HEC-RAS 1D/2D水动力与水环境模拟技术案例实践
    VUEX的基础使用存值及异步
    解决rosbag播放‘[FATAL] [1662351033.122111074]: Expected INDEX_DATA record‘
    【数据挖掘】2022年2023届秋招宏瓴科技公司机器学习算法工程师 笔试题
    论文指标评价体系及权重计算
  • 原文地址:https://blog.csdn.net/qq_49137582/article/details/127679518