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

本文主要是介绍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")@ResponseBodypublic 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字节,也就是1MBupload.setFileSizeMax(1024*1024*10);//设置上传文件总量的最大值,最大值=同时上传的多个文件的大小的最大值的和,目前设置为10MBupload.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")@ResponseBodypublic 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";}

这篇关于fileupload插件调用upload.parseRequest(request)解析得到空值问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1128311

相关文章

Kotlin Map映射转换问题小结

《KotlinMap映射转换问题小结》文章介绍了Kotlin集合转换的多种方法,包括map(一对一转换)、mapIndexed(带索引)、mapNotNull(过滤null)、mapKeys/map... 目录Kotlin 集合转换:map、mapIndexed、mapNotNull、mapKeys、map

nginx中端口无权限的问题解决

《nginx中端口无权限的问题解决》当Nginx日志报错bind()to80failed(13:Permissiondenied)时,这通常是由于权限不足导致Nginx无法绑定到80端口,下面就来... 目录一、问题原因分析二、解决方案1. 以 root 权限运行 Nginx(不推荐)2. 为 Nginx

解决1093 - You can‘t specify target table报错问题及原因分析

《解决1093-Youcan‘tspecifytargettable报错问题及原因分析》MySQL1093错误因UPDATE/DELETE语句的FROM子句直接引用目标表或嵌套子查询导致,... 目录报js错原因分析具体原因解决办法方法一:使用临时表方法二:使用JOIN方法三:使用EXISTS示例总结报错原

Windows环境下解决Matplotlib中文字体显示问题的详细教程

《Windows环境下解决Matplotlib中文字体显示问题的详细教程》本文详细介绍了在Windows下解决Matplotlib中文显示问题的方法,包括安装字体、更新缓存、配置文件设置及编码調整,并... 目录引言问题分析解决方案详解1. 检查系统已安装字体2. 手动添加中文字体(以SimHei为例)步骤

SpringSecurity整合redission序列化问题小结(最新整理)

《SpringSecurity整合redission序列化问题小结(最新整理)》文章详解SpringSecurity整合Redisson时的序列化问题,指出需排除官方Jackson依赖,通过自定义反序... 目录1. 前言2. Redission配置2.1 RedissonProperties2.2 Red

nginx 负载均衡配置及如何解决重复登录问题

《nginx负载均衡配置及如何解决重复登录问题》文章详解Nginx源码安装与Docker部署,介绍四层/七层代理区别及负载均衡策略,通过ip_hash解决重复登录问题,对nginx负载均衡配置及如何... 目录一:源码安装:1.配置编译参数2.编译3.编译安装 二,四层代理和七层代理区别1.二者混合使用举例

nginx -t、nginx -s stop 和 nginx -s reload 命令的详细解析(结合应用场景)

《nginx-t、nginx-sstop和nginx-sreload命令的详细解析(结合应用场景)》本文解析Nginx的-t、-sstop、-sreload命令,分别用于配置语法检... 以下是关于 nginx -t、nginx -s stop 和 nginx -s reload 命令的详细解析,结合实际应

MyBatis中$与#的区别解析

《MyBatis中$与#的区别解析》文章浏览阅读314次,点赞4次,收藏6次。MyBatis使用#{}作为参数占位符时,会创建预处理语句(PreparedStatement),并将参数值作为预处理语句... 目录一、介绍二、sql注入风险实例一、介绍#(井号):MyBATis使用#{}作为参数占位符时,会

java使用protobuf-maven-plugin的插件编译proto文件详解

《java使用protobuf-maven-plugin的插件编译proto文件详解》:本文主要介绍java使用protobuf-maven-plugin的插件编译proto文件,具有很好的参考价... 目录protobuf文件作为数据传输和存储的协议主要介绍在Java使用maven编译proto文件的插件

PostgreSQL的扩展dict_int应用案例解析

《PostgreSQL的扩展dict_int应用案例解析》dict_int扩展为PostgreSQL提供了专业的整数文本处理能力,特别适合需要精确处理数字内容的搜索场景,本文给大家介绍PostgreS... 目录PostgreSQL的扩展dict_int一、扩展概述二、核心功能三、安装与启用四、字典配置方法