图片上传对一些后台系统来讲,是一个比较常见的功能,我们有一个项目的后台项目是用html+JS开发的,今天在做后台系统的时候,需要做一些配置项的保存,涉及到图片上传,在Html页面中增加图片上传的代码:
<div class="form-group" id="imgDiv"> <label class="col-sm-3 control-label"> 图片: </label> <div class="fileinput fileinput-new col-sm-7" data-provides="fileinput"> <input type="hidden" id="img" name="img"> <input class="file" type="file" id="uploadfile" name="uploadfile"/> </div> </div>
Html页面需要引用一些js和css样式
<link href="${ctxPath}/static/css/fileinput.min.css" rel="stylesheet" type="text/css"/> <script src="${ctxPath}/static/js/fileinput.js" type="text/javascript"></script> <script src="${ctxPath}/static/js/zh.js" type="text/javascript"></script>
JS中图片上传的代码如下:
$("#uploadfile").fileinput({ language: 'zh', //设置语言 allowedFileExtensions: ['jpg', 'png', 'gif'],//接收的文件后缀 uploadUrl: "提交数据的controller url", uploadAsync: false, //默认异步上传 showUpload: false, //是否显示上传按钮 showRemove: true, //显示移除按钮 showPreview: true, //是否显示预览 showCaption: true,//是否显示标题 maxFileSize: 800,//上传文件最大的尺寸 browseClass: "btn btn-primary", //按钮样式 dropZoneEnabled: false,//是否显示拖拽区域 enctype: 'multipart/form-data', validateInitialCount: true, uploadExtraData: function () { return InfoDlg.InfoData;//当前js页面收集数据的data对象 }, fileActionSettings: { showDrag: true, showRemove: true, showUpload: false, showZoom: false } }).on("filebatchuploadsuccess", function (event, data, previewId, index) { var response = data.response; if (response.code === 200) { Feng.info("保存成功!"); window.parent.xxxxxxxx.table.refresh();//父类页面刷新 InfoDlg.close();//当前配置页面关闭 } else { Feng.error("保存失败!" + response.message + "!"); } });
之前也做过很多次了,开发完成之后自测一下上传,图片上传之后,页面也有返显,但是在提交的时候报错了,看了一下日志,报了java.lang.ClassCastException: org.apache.shiro.web.servlet.ShiroHttpServletRequest cannot be cast to org.springframework.web.multipart.MultipartHttpServletRequest这个异常,
controller中代码如下:
@Permission @RequestMapping(value = "/add") @ResponseBody public Object add(Vo vo, HttpServletRequest request) { MultiValueMap<String, MultipartFile> multiFileMap = ((MultipartHttpServletRequest) request).getMultiFileMap(); List<MultipartFile> uploadfile = multiFileMap.get("uploadfile"); if (uploadfile != null && uploadfile.size() != 0) { String img = ImgUtils.saveImg("img"); if (!img.equals("")) { vo.setImg(img); } else { return new ErrorTip(500, "图片保存失败"); } } return commonSubmit(vo); }
打了一下断点,看了一下,HttpServletRequest进来的时候,是ShiroHttpServletRequest,然后类转换异常了,看了一下别人提供的解决方法,有以下几种:
1.增加spring-mvc.xml配置
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="maxUploadSize"> <!-- 最大上传文件大小 100M--> <value>104857600</value> </property> <property name="maxInMemorySize"> <!-- 最大上传缓存大小 4k--> <value>4096</value> </property> </bean>
2.将ShiroHttpServletRequest转换成commen httpRequest:
StandardServletMultipartResolver resolver = new StandardServletMultipartResolver();
MultipartHttpServletRequest multipartRequest = resolver.resolveMultipart(request);
3.form中添加参数:
enctype="multipart/form-data"
<form class="form-horizontal" id="id" enctype="multipart/form-data">
第一个方法不适用我们这边,我们没用自己配置的bean,所以用了第二个方法试了一下,发现还是没解决问题,controller不能解决问题,页面中enctype="multipart/form-data"属性已将加过了,思路还是回到了页面上来,html页面不会有问题,看一下JS发送请求的问题,仔细看了一下提交数据的接口,终于发现了问题,有图片上传的功能,提交请求数据方法直接使用
$('#uploadfile').fileinput('upload');
通过这个方法就可以实现图片上传加数据提交,但是我这里用了ajax提交
var ajax = new $ax("提交数据的controller url", function (data) { Feng.success("添加成功!"); window.parent.xxxxxxxx.table.refresh();//父类页面刷新 InfoDlg.close();//当前配置页面关闭 }, function (data) { Feng.error("添加失败!" + data.responseJSON.message + "!"); }); ajax.set(this.InfoData); ajax.start();
这里做了一下修改,如果有图片,则使用fileinput,没有图片的话在用ajax提交数据,
if($('#uploadfile').fileinput('getFilesCount') > 0){ $('#uploadfile').fileinput('upload'); }else{ var ajax = new $ax("提交数据的controller url", function (data) { Feng.success("添加成功!"); window.parent.xxxxxxxx.table.refresh();//父类页面刷新 InfoDlg.close();//当前配置页面关闭 }, function (data) { Feng.error("添加失败!" + data.responseJSON.message + "!"); }); ajax.set(this.InfoData); ajax.start(); }
问题解决。有被自己蠢哭,页面调试涉及的问题比较多,做页面的时候,还是希望大家多留意。