fileupload插件调用upload.parseRequest(request)解析得到空值问题

Java Web下接收文件常基于fileupload插件实现,其一般代码如下:
index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"/>
    <title>Title</title>
</head>
<body>
<form action="/test/file" enctype="multipart/form-data"
      method="post">
    上传用户:<input type="text" name="username"/><br/>
    上传文件:<input type="file" name="file2"/><br/>
    <input type="submit" value="提交"/>
</form>
</body>
</html>

对应的后台Controller代码:

    @RequestMapping(value = "/test/file")
    @ResponseBody
    public String file (HttpServletRequest request,HttpServletResponse response) throws IOException{
        response.setContentType("application/json;charset=utf-8");
        try{
            //使用Apache文件上传组件处理文件上传步骤:
            //1、创建一个DiskFileItemFactory工厂
            DiskFileItemFactory factory = new DiskFileItemFactory();
            //设置工厂的缓冲区的大小,当上传的文件大小超过缓冲区的大小时,就会生成一个临时文件存放到指定的临时目录当中。
            factory.setSizeThreshold(1024*100);//设置缓冲区的大小为100KB,如果不指定,那么缓冲区的大小默认是10KB
            /*//设置上传时生成的临时文件的保存目录
            factory.setRepository(tmpFile);*/
            //2、创建一个文件上传解析器
            ServletFileUpload upload = new ServletFileUpload(factory);
            //监听文件上传进度
            upload.setProgressListener(new ProgressListener(){
                public void update(long pBytesRead, long pContentLength, int arg2) {
                    System.out.println("文件大小为:" + pContentLength + ",当前已处理:" + pBytesRead);
                }
            });
            //解决上传文件名的中文乱码
            upload.setHeaderEncoding("UTF-8");
            //3、判断提交上来的数据是否是上传表单的数据
            if(!ServletFileUpload.isMultipartContent(request)){
                //按照传统方式获取数据
                return;
            }

            //设置上传单个文件的大小的最大值,目前是设置为1024*1024字节,也就是1MB
            upload.setFileSizeMax(1024*1024*10);
            //设置上传文件总量的最大值,最大值=同时上传的多个文件的大小的最大值的和,目前设置为10MB
            upload.setSizeMax(1024*1024*30);
            //4、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List<FileItem>集合,每一个FileItem对应一个Form表单的输入项
            List<FileItem> list = upload.parseRequest(request);
            for(FileItem item : list){
                //如果fileitem中封装的是普通输入项的数据
                if(item.isFormField()){
                    String name = item.getFieldName();
                    //解决普通输入项的数据的中文乱码问题
                    String value = item.getString("UTF-8");
                    //value = new String(value.getBytes("iso8859-1"),"UTF-8");
                    System.out.println(name + "=" + value);
                }else{//如果fileitem中封装的是上传文件
                    //得到上传的文件名称,
                    String filename = item.getName();
                    System.out.println(filename);
                    if(filename==null || filename.trim().equals("")){
                        continue;
                    }
                    //注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名是带有路径的,如:  c:\a\b\1.txt,而有些只是单纯的文件名,如:1.txt
                    //处理获取到的上传文件的文件名的路径部分,只保留文件名部分
                    filename = filename.substring(filename.lastIndexOf("\\")+1);
                    //得到上传文件的扩展名
                    String fileExtName = filename.substring(filename.lastIndexOf(".")+1);
                    filename = filename.substring(0,filename.lastIndexOf("."));
                    //如果需要限制上传的文件类型,那么可以通过文件的扩展名来判断上传的文件类型是否合法
                    System.out.println("上传的文件的扩展名是:"+fileExtName);
                    //保存文件
                    FileManager fileManager = new FileManager();
                    if(FileManager.ERROR.equals(fileManager.save(filename,fileExtName,"song",item.getInputStream()))){
                        return JsonUtil.statusResponse(1,"上传文件失败",null);
                    }
                }
            }
        }catch (FileUploadBase.FileSizeLimitExceededException e) {
            e.printStackTrace();
            return JsonUtil.statusResponse(1,"单个文件超出最大值!!!",null);
        }catch (FileUploadBase.SizeLimitExceededException e) {
            e.printStackTrace();
            return JsonUtil.statusResponse(1,"上传文件的总的大小超出限制的最大值!!!",null);
        }catch (Exception e) {
            e.printStackTrace();
            return JsonUtil.statusResponse(1,"其他异常,上传失败!!!",null);
        }
        return JsonUtil.statusResponse(0,"上传文件成功",fileManager.getFileURI(filename,fileExtName));
    }

我是在SpringBoot下测试时,发现的该问题,即在解析请求时List list = upload.parseRequest(request);得到的list size=0,也就是根本没有得到文件数据。我在网上搜索该问题的解决方法,大致有以下两种:
(1)原因在于Spring的配置文件中已经配置了MultipartResolver,导致文件上传请求已经被预处理过了,所以此处解析文件列表为空,对应的做法是删除该段配置。
(2)认为是structs的过滤器导致请求已被预处理,所以也要修改对应过滤器的配置。
然而,在SpringBoot下,上述两种解决方法不可能做到,因为SpringBoot的相关配置都是自己完成的,根本没有显示的配置文件。况且以上两种解决方法,修改配置文件可能影响整个工程的其他部分,所以得另寻方案。
我通过断点调试该Controller代码,发现传入的参数HttpServletRequest实例已经为StandardMultipartHttpServletRequest 对象了,且其结构中包含整个form表单的所有字段信息,我就想,区别于网上已有的两种解决方案,总是想避免这种预处理,何不就利用这种预处理,来简化自己的代码结构呢?于是就有了下面的解决代码。其方法很简单,就是对传入的request做强制转型,从而可以根据StandardMultipartHttpServletRequest 实例方法得到相关form表单数据,从而大大简化代码结构,示意如下:

@RequestMapping(value = "/file")
    @ResponseBody
    public String file (HttpServletRequest request, HttpServletResponse response) throws IOException {
        ...
        try {
            StandardMultipartHttpServletRequest req = (StandardMultipartHttpServletRequest) request;
            Iterator<String> iterator = req.getFileNames();
            while (iterator.hasNext()) {
                MultipartFile file = req.getFile(iterator.next());
                String fileNames = file.getOriginalFilename();
                int split = fileNames.lastIndexOf(".");
            //存储文件
            //文件名  fileNames.substring(0,split)
            //文件格式   fileNames.substring(split+1,fileNames.length())
           //文件内容 file.getBytes()
           ...
            }
        }catch (Exception e){
            e.printStackTrace();
            return "fail";
        }
        return "success";
    }
  • 28
    点赞
  • 73
    收藏
    觉得还不错? 一键收藏
  • 19
    评论
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值