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.文件的边界格式读取有问题 2.可能电脑又加密软件啥的

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

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

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

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

后来,我想着有没有可能是它本来写的代码就有问题,于是,我就把他的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();

            //后面的就是可以对文件输入流进行相关操作了
            ... ...
            //以下省略

        }
        
    }
   
    
    
}

总结

  • 在优化别人代码的时候,别人代码不一定正确
  • 在写代码的时候要有写注释的好习惯
  • 解决完bug后需要即使进行总结
  • 问题解决不了不要着急,慢慢来
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱学习的大雄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值