web 文件上传以及getInputStream() has already been called for this request问题的解决
程序员文章站
2022-05-01 21:54:31
...
效果图:
一、点击的按钮代码
<button type="button" class="btn btn-default" onclick=""data-toggle="modal"
data-target="#importExcelModel">
<i class="fa fa-cogs"></i> 导入会员
</button>
二、导入文本的弹出框代码
<div z-index="1" class="modal fade" id="importExcelModel"
tabindex="1" role="dialog" aria-labelledby="importExcelModel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"
aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title" id="importExcelModel">导入会员</h4>
</div>
<div class="modal-body">
<!-- accept=".xls" 用于设置能够接受的文件类型 -->
<form id="importFile" name="importFile"
class="form-horizontal" method="post"
enctype="multipart/form-data">
<div class="box-body">
<div>
<label class="control-label">请选择要导入的Excel文件:</label> <input
id="excelFile" name="excelFile" class="file-loading"
data-show-preview="false" type="file" multiple
accept=".xls"> <br>
</div>
<!-- -----------a标签下载模板----------->
<a href="./template/模板-批量导入会员.xls"
download="模板-批量导入会员.xls">下载模板</a>
</div>
</form>
</div>
<div class="modal-footer">
<button id="importModelColse" type="button"
class="btn btn-default" data-dismiss="modal">关闭</button>
</div>
</div>
</div>
</div>
需要导入
三、导入文本的js代码
function initUpload(ctrlName) {
var uploadUrl=urlUtils.projectRootUrl() + urlUtils.modelUrl.mem + urlUtils.logicUrl.importMemberExcel;
var control = $('#' + ctrlName);
control.fileinput({
language: 'zh', //设置语言
uploadUrl: uploadUrl, //上传的地址
uploadAsync: true, //默认异步上传
showCaption: true,//是否显示标题
showUpload: true, //是否显示上传按钮
browseClass: "btn btn-primary", //按钮样式
allowedFileExtensions: ["xls"], //接收的文件后缀
maxFileCount: 10,//最大上传文件数限制
previewFileIcon: '<i class="glyphicon glyphicon-file"></i>',
showPreview: true, //是否显示预览
previewFileIconSettings: {
'docx': '<i ass="fa fa-file-word-o text-primary"></i>',
'xlsx': '<i class="fa fa-file-excel-o text-success"></i>',
'xls': '<i class="fa fa-file-excel-o text-success"></i>',
'pptx': '<i class="fa fa-file-powerpoint-o text-danger"></i>',
'jpg': '<i class="fa fa-file-photo-o text-warning"></i>',
'pdf': '<i class="fa fa-file-archive-o text-muted"></i>',
'zip': '<i class="fa fa-file-archive-o text-muted"></i>',
},
uploadExtraData: function () {
var extraValue = "test";
return {"excelType": extraValue};
}
})
$("#excelFile").on("fileuploaded", function (event, data, previewId, index) {
console.log(data);
//根据后台返回的状态自己加判断
//todo
//重置
$("#excelFile").fileinput("clear");
$("#excelFile").fileinput("reset");
$('#excelFile').fileinput('refresh');
$('#excelFile').fileinput('enable');
}
});
}
四、后台接受文件流的代码
@PostMapping(value = "/importMemberExcel")
public OperateResponse<?> importMemberExcel(HttpServletRequest request) {
OperateResponse<Map<String, Object>> importMemberExcelOperateResponse;
try {
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setFileSizeMax(10 * 1024 * 1024); // 单个文件大小限制
upload.setSizeMax(50 * 1024 * 1024); // 总文件大小限制
upload.setHeaderEncoding("UTF-8"); // 对中文文件编码处理
List<FileItem> fileList = null;
if (ServletFileUpload.isMultipartContent(request)) {
fileList = upload.parseRequest(request);
}
// 取出文件的流
InputStream is = fileList.get(0).getInputStream();
is.close();
// 关闭workbook
workbook.close();
} catch (Exception e) {
e.printStackTrace();
//写自己要返回的异常信息 todo
return null;
}
}
在后台如果出现getInputStream() has already been called for this request 这个异常的话,在使用ssm框架的情况下就是你配置了
springmvc.xml的文件上传或者你在接收文件流的时候使用了MultipartFile进行接收,这样在使用upload.parseRequest(request)就获取不到文件的集合,在执行fileList.get(0).getInputStream()就会出现异常。原因是request不能重复解析或者请求。解决办法是选择其中一种,要么删除springmvc.xml下的下面的配置及接收文件时的MultipartFile接受,要么不使用上面代码。
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize"><value>100000</value></property>
<property name="defaultEncoding"><value>UTF-8</value></property>
</bean>
五、如果上传excel文件,可以使用下面方式解析。
public OperateResponse<?> importMemberExcel(HttpServletRequest request) {
OperateResponse<Map<String, Object>> importMemberExcelOperateResponse;
try {
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setFileSizeMax(10 * 1024 * 1024); // 单个文件大小限制
upload.setSizeMax(50 * 1024 * 1024); // 总文件大小限制
upload.setHeaderEncoding("UTF-8"); // 对中文文件编码处理
List<FileItem> fileList = null;
if (ServletFileUpload.isMultipartContent(request)) {
fileList = upload.parseRequest(request);
}
// 取出文件的流
InputStream is = fileList.get(0).getInputStream();
// 新建工作簿
HSSFWorkbook workbook = new HSSFWorkbook(is);
is.close();
// 由于导入数据 无法在前端校验 在接入层校验数据
//自己使用 正则校验
// 遍历sheet页
for (int numSheet = 0; numSheet < workbook.getNumberOfSheets(); numSheet++) {
HSSFSheet sheet = workbook.getSheetAt(numSheet);
if (sheet == null) {
continue;
}
// 从第三行开始读取数据
for (int rowNum = 3; rowNum <= sheet.getLastRowNum(); rowNum++) {
HSSFRow row = sheet.getRow(rowNum);
int minCellNum = row.getFirstCellNum();
int maxCellNum = row.getLastCellNum();
for (int i = minCellNum; i < maxCellNum; i++) {
HSSFCell cell = row.getCell(i);
//todo 自己需要取出的单元格及要存放的形式
}
}
}
// 关闭workbook
workbook.close();
return importMemberExcelOperateResponse;
} catch (Exception e) {
logTool.error(logger, "importMemberExcel Error", request, e);
e.printStackTrace();
// todo
return null;
}
}