今天需要做一个上传图片的功能,由于框架里面没有带,上网搜了下。看到有spring mvc的图片上传,而且有例子,刚好是自己需要的,直接粘贴复制下。参考:

http://blog.csdn.net/luckey_zh/article/details/46867957#

很简单,使用了commons-upload和commons-io包,配置文件位置后,页面form表单这几设置,然后就好了。

配置完后,自己运行却发现,上传报错了:

org.apache.tomcat.util.http.fileupload.FileUploadException: the request was rejected because no multipart boundary was found
org.apache.tomcat.util.http.fileupload.FileUploadBase$FileItemIteratorImpl.<init>(FileUploadBase.java:840)
org.apache.tomcat.util.http.fileupload.FileUploadBase.getItemIterator(FileUploadBase.java:259)
org.apache.tomcat.util.http.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:283)
org.apache.catalina.connector.Request.parseParts(Request.java:2811)
org.apache.catalina.connector.Request.getParts(Request.java:2729)
org.apache.catalina.connector.RequestFacade.getParts(RequestFacade.java:1075)
org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.parseRequest(StandardMultipartHttpServletRequest.java:84)
org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.<init>(StandardMultipartHttpServletRequest.java:77)
org.springframework.web.multipart.support.StandardServletMultipartResolver.resolveMultipart(StandardServletMultipartResolver.java:76)
org.springframework.web.servlet.DispatcherServlet.checkMultipart(DispatcherServlet.java:1073)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:912)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:868)
javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
com.springapp.mvc.filter.UploadImageInterceptor.doFilter(UploadImageInterceptor.java:27)

    上网搜了下,原来是因为自己使用的是ajax提交的,但是ajax默认的content-type是x-www-form-urlencoded,这样提交文件是无法生效的。由于框架的原因,如果改成form提交和其他页面相差太大,而且不一定能解决问题,于是决定继续顺着ajax为何不能提交这个坑继续下去。

然后上网继续搜,发现需要设置ajax的几个属性为false,这样才能提交:(参考http://www.jianshu.com/p/46e6e03a0d53)

 $.ajax({
url: "ur",
contentType: false, //必须设置
processData: false, //必须设置
cache: false, //设置为false
// data: $(form).serialize(),
data: new FormData($('#myForm')[0]),
type: "POST",

  刚开始用    data: $(form).serialize(), 结果不行,换成了下面的这种,然而又有问题了。页面的元素通过request.getParameter("")居然获取不到了。。。



  继续搜,为何搜不到。。。然后在一篇文章上面看到了下面的说法:(参考:http://www.chongchonggou.com/g_464425214.html)

   设置提交方式为enctype="multipart/form-data"后,使用request.getParameter(“”)是获取不到页面的formData的数据的。 上面也说了解决办法,就是使用common-smartupload进行获取,我就是

通过这种方式获取的,不过碰到了几个问题,比如乱码问题、windows/linux 分隔符问题以及文件找不到等小问题,最后总算解决了。另外附上一篇一个大神之前写的一篇文章。

   http://www.cnblogs.com/xdp-gacl/p/4200090.html

附上自己的代码以及实现:

前端:
 <link href="#springUrl('/static/css/bootstrap.min.css')" rel="stylesheet">
<link href="#springUrl('/static/css/style.css')" rel="stylesheet">
<link href="#springUrl('/static/css/datetimepicker.css')" rel="stylesheet">
<body class="white-bg">
<div class="ibox-content" style="width: 430px;">
<form id="myForm" class="form-horizontal" autocomplete="off" data-validator-option="{theme:'default'}" enctype="multipart/form-data" >
<input type="hidden" name="id" value="$!{activity.id}">
<div class="form-group"><label class="col-sm-2 control-label">xxx</label>
<div class="col-sm-10">
<input type="text" class="form-control" value="$!{activity.title}" name="title" data-rule="xxx:required;title">
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group"><label class="col-sm-2 control-label">xxx</label>
<div class="col-sm-10">
<textarea class="form-control" value="$!{activity.content}" name="content" data-rule="xxx:required;content">$!{activity.content}</textarea>
</div>
</div> <div class="hr-line-dashed"></div>
<div class="form-group"><label class="col-sm-2 control-label">xxx</label> #if(${activity.pic} == "null")
<div class="col-sm-10">
<input type="file" name="pic" id="pic" data-rule="xxx:required;pic"/>
</div>
#end
#if(${activity.pic} != "null")
<div class="col-sm-10">
<input type="file" name="pic" id="pic" />
</div> <img alt="xxx" src="#springUrl('/static/upload/images/f854d8f0186649fcac9a01b4a5da2c8d.jpg')" style="height:100%; width:100%">
#end
</div> <div class="hr-line-dashed"></div>
<div class="form-group"><label class="col-sm-2 control-label">xxx/label>
<div class="col-sm-10">
<select class="form-control m-b" name="tag">
<option value="1">xx</option>
<option value="2">xx</option>
<option value="3">xx</option>
<option value="4">xx</option>
</select>
</div>
</div>
<div class="form-group"><label class="col-sm-2 control-label">xx</label>
<div class="col-sm-10">
<input type="text" class="form-control" value="$!{activity.places}" name="places" data-rule="xx:required;places">
</div>
</div>
<div class="form-group"><label class="col-sm-2 control-label">xx</label>
<div class="col-sm-10">
<input type="text" class="form-control" value="$!{activity.deposit}" name="deposit" data-rule="xx:required;deposit">
</div>
</div>
<div class="form-group"><label class="col-sm-2 control-label">xx</label>
<div class="col-sm-10">
<input type="text" class="form-control" value="$!{activity.fullPrice}" name="fullPrice" data-rule="xx:required;fullPrice">
</div>
</div>
<div class="form-group"><label class="col-sm-2 control-label">xx</label>
<div class="col-sm-10">
<input type="text" class="form-control" value="$!{activity.detailAddress}" name="detailAddress" data-rule="xx:required;detailAddress">
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label class="control-label">xx:</label>
<div class="controls">
<input value="$!date.format('yyyy-MM-dd HH:mm:ss ',$!activity.beginTime)" name="beginTime" id="beginTime">
</div>
</div>
</div>
</div> <div class="row">
<div class="col-md-6">
<div class="form-group">
<label class="control-label">xx:</label>
<div class="controls">
<input value="$!date.format('yyyy-MM-dd HH:mm:ss ',$!activity.endTime)" name="endTime" id="endTime">
</div>
</div>
</div>
</div> <div class="hr-line-dashed"></div>
<div class="form-group">
<div class="text-center">
<button class="btn btn-primary" type="submit">#if($!{activity})修 改#else提 交#end</button>
</div>
</div>
</form>
</div>
<script src="#springUrl('/static/js/jquery-2.1.1.js')"></script>
<script src="#springUrl('/static/plugins/nice-validator-0.8.1/jquery.validator.js?local=zh-CN')"></script>
<script src="#springUrl('/static/js/common.js')"></script>
<script src="#springUrl('/static/js/bootstrap-datetimepicker.js')"></script>
<script src="#springUrl('/static/js/bootstrap-datetimepicker.zh-CN.js')"></script> <script type="text/javascript">
$('#beginTime').datetimepicker({
format: 'yyyy-mm-dd hh:ii:ss',
language: 'zh-CN',
autoclose: true
});
$('#endTime').datetimepicker({
format: 'yyyy-mm-dd hh:ii:ss',
language: 'zh-CN',
autoclose: true
}); $("#myForm").validator({
valid: function(form){
var me = this;
// 提交表单之前,hold住表单,防止重复提交
me.holdSubmit();
$.ajax({
url: "#springUrl('/activities/editActivity')",
contentType: false,
processData: false,
cache: false,
// data: $(form).serialize(),
data: new FormData($('#myForm')[0]),
type: "POST",
success: function(data){
var d = JSON.parse(data);
if(d.success && d.data){
window.parent.location.reload();
//当你在iframe页面关闭自身时
//var index = parent.layer.getFrameIndex(window.name); //先得到当前iframe层的索引
//parent.layer.close(index); //再执行关闭
} else {
//失败,提交表单成功后,释放hold,如果不释放hold,就变成了只能提交一次的表单
me.holdSubmit(false);
}
}
});
}
});
</script>
</body>
</html>

  后端代码以及实现:

  @ResponseBody
@Permission("5001")
@RequestMapping(value = "/editActivity")
public String editActivity(HttpServletRequest request,Activity activity) throws ParseException {
activity = new Activity();
boolean rlt = false;
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
//获得物理路径webapp所在路径
String pathRoot = request.getSession().getServletContext().getRealPath("");
String path="";
upload.setHeaderEncoding("UTF-8");// 解决乱码关键
Map<String,String> map = new HashMap<>();
try {
List<FileItem> list = upload.parseRequest(request);
for(FileItem item : list){
if(item.isFormField()){
//注意此处是没有图片的其他属性
String value = null;
try {
value = new String(item.getString("utf-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
map.put(item.getFieldName(),value);
}else{
//生成uuid作为文件名称
String uuid = UUID.randomUUID().toString().replaceAll("-","");
//获得文件后缀名称
String imageName=item.getName().substring(item.getName().lastIndexOf(".")+1);
String fileUrl = Constant.FILE_URL;
path = fileUrl + uuid+"."+imageName;
map.put(item.getFieldName(),Constant.FILE_URL+uuid+"."+imageName);
upload.setHeaderEncoding("UTF-8");
try {
//得到上传文件的扩展名
String fileExtName = imageName.substring(imageName.lastIndexOf(".")+1);
//如果需要限制上传的文件类型,那么可以通过文件的扩展名来判断上传的文件类型是否合法
System.out.println("上传的文件的扩展名是:"+fileExtName);
//获取item中的上传文件的输入流
InputStream in = item.getInputStream();
//得到文件保存的名称
String saveFilename = path;
//得到文件的保存目录
String realSavePath = makePath(pathRoot, fileUrl);
//创建一个文件输出流
FileOutputStream out = new FileOutputStream(pathRoot+path);
//创建一个缓冲区
byte buffer[] = new byte[1024];
//判断输入流中的数据是否已经读完的标识
int len = 0;
//循环将输入流读入到缓冲区当中,(len=in.read(buffer))>0就表示in里面还有数据
while((len=in.read(buffer))>0){
//使用FileOutputStream输出流将缓冲区的数据写入到指定的目录(savePath + "\\" + filename)当中
out.write(buffer, 0, len);
}
//关闭输入流
in.close();
//关闭输出流
out.close();
//删除处理文件上传时生成的临时文件
item.delete();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} catch (FileUploadException e) {
e.printStackTrace();
} activity.setBeginTime(DateUtils.toDate(map.get("beginTime"),"yyyy-MM-dd HH:mm:ss") );
activity.setPlaces(Integer.valueOf(map.get("places")));
activity.setCity(map.get("city"));
activity.setContent(map.get("content"));
activity.setTag(Integer.valueOf(map.get("tag")));
activity.setDeposit(new BigDecimal(map.get("deposit")));
activity.setDetailAddress(map.get("detailAddress"));
activity.setPic(map.get("pic"));
activity.setEndTime(DateUtils.toDate(map.get("endTime"),"yyyy-MM-dd HH:mm:ss"));
activity.setTitle(map.get("title"));
activity.setUpdateTime(new Date());
if(StringUtils.isNotBlank(map.get("id"))){
activity.setId(Long.valueOf(map.get("id")));
rlt = activityService.updateById(activity);
}else {
activity.setAddTime(new Date());
rlt = activityService.insert(activity);
}
return callbackSuccess(rlt);
}

配置文件这块,原来的springmvc 是有这样的一段配置的:

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8"/>
<!– 最大内存大小 –>
<property name="maxInMemorySize" value="10240"/>
<!– 最大文件大小,-1为不限制大小 –>
<property name="maxUploadSize" value="-1"/>
</bean>

  

但是实际做后发现,配置后使用common-fileupload上传不起作用,原因就是因为fileUpload解析过request,所以导致上传为空。


所以才有了上面的自己写代码来上传。参考:http://zzc1684.iteye.com/blog/2258463

关于使用ajax上传图片问题的更多相关文章

  1. ajaxfileUpload ajax 上传图片使用

    前台html: <div class="b-mg15 img-text" room_id="<?= $items['id'] ?>"> ...

  2. ajax上传图片

    选择文件后 ajax上传图片到后台,后台执行保存操作,返回上传的图片路径,显示到页面 需要引入ajaxfileupload.js js代码 <script type="text/jav ...

  3. 使用ajax上传图片,支持图片即时浏览,支持js图片压缩后上传给服务器

    使用ajax上传图片,支持图片即时浏览,支持js图片压缩后上传给服务器 ajax上传主要使用了 var reader = new FileReader() 此方法 js图片压缩主要是利用canvas进 ...

  4. Ajax上传图片以及上传之前先预览

    手头上有几个小项目用到了easyUI,一开始决定使用easyUI就注定了项目整体上前后端分离,基本上所有的请求都采用Ajax来完成.在文件上传的时候用到了Ajax上传文件,以及图片在上传之前的预览效果 ...

  5. asp.net core 通过ajax上传图片及wangEditor图片上传

    asp.net core 通过ajax上传图片 .net core前端代码,因为是通过ajax调用,首先要保证ajax能调用后台代码,具体参见上一篇.net core 使用ajax调用后台代码. 前端 ...

  6. vuejs使用FormData对象,ajax上传图片文件

    我相信很多使用vuejs的朋友,都有采用ajax上传图片的需求,因为前后端分离后,我们希望都能用ajax来解决数据问题,传统的表单提交会导致提交成功后页面跳转,而使用ajax能够无刷新上传图片等文件. ...

  7. php form表单ajax上传图片方法

    form表单ajax上传图片方法 先引用jquery.form.js 前台代码<pre><form id="form1"> <input id=&qu ...

  8. 使用ajax上传图片,并且使用canvas实现出上传进度效果

    前端代码: <%@ page contentType="text/html;charset=UTF-8" language="java" %> &l ...

  9. 十六、ajax上传图片 mvc

    一.ajax上传图片 mvc 前台html     <img id="uploadimg1" class="uploadimg" src="~/ ...

  10. 移动端压缩并ajax上传图片解决方案

    1.需求 做一个前端可压缩并且上传图片到后台的功能 2.使用组件 用到的主要是jq和LocalResizeIMG这2个库 3.使用方法 a.引入脚本文件 <script type='text/j ...

随机推荐

  1. Win10远程连接,出现身份验证错误。远程计算机要求的函数不受支持 这可能是由于CredSSP加密Oracle修正 。

    问题: 升级至win10 最新版本10.0.17134,安装最新补丁后无法远程win server 2016服务器,报错信息如下: 出现身份验证错误,要求的函数不正确,这可能是由于CredSSP加密O ...

  2. 如何打开java监控

    直接在cmd中输入 1.jconsole 2.jvisualvm

  3. 小白详细解析C#反射特性实例

    套用MSDN上对于反射的定义:反射提供了封装程序集.模块和类型的对象(Type 类型).可以使用反射动态创建类型的实例,将类型绑定到现有对象,或从现有对象获取类型并调用其方法或访问其字段和属性.如果代 ...

  4. SQL基础语法select|insert|update|delete(增删改查) 简单使用

    以下案列以此表举例 1.select(查询) select简单的查询分为两种 注:字段也就是表结构中的列的名称 第一种: select  字段名  from  表名 此种查询只列出你所需要查询的字段, ...

  5. APP的功能分类及打包与发布的分类方式

    智能手机的出现改变了我们的生活,同时各种各样的APP充斥在我们的手机当中.那么我先现在在来熟悉一下APP的分类及其用途:工具类.社交类.信息类.娱乐类.生活类等几大类.我么了解了APP的用途分类,那么 ...

  6. java有序map

    我们知道TreeMap的key是有顺序的,是自然顺序,也可以指定比较函数. 但TreeMap默认不是按插入的顺序.  为了让Map按照插入顺序显示,可以使用LinkedHashMap吧. 它内部有一个 ...

  7. swift与OC混编之调用函数

    在桥接头文件里#import oc的.h文件,整个swift工程都能使用该oc文件,在.h里暴露的方法都能被该工程使用 //oc文件 TestOC.h #import @interface TestO ...

  8. CentOS7 配置免密登陆

    首先我通过VMware配置了4台机器 然后依次更改每台机器的hosts文件为:   (/etc/hosts) 192.168.32.128 linux1192.168.32.130 linux2192 ...

  9. Android表格布局之设置边框

    Android表格布局本身没有边框,不过可以通过背景色的设置可以实现表格边框的显示. 首先可以设置TableRow的背景色,然后设置内容的背景色.根据它们的颜色差就出现了边框.只要微调Content与 ...

  10. GITHUB一个新的项目发布

    经过一段时间的积累,写了一些代码,发现好多功能有好几个系统都在用,但是公司的开发过程中,并没有一个对通用功能提取整合普遍化的一个流程,所以就自己将在项目开发过程中遇到的一些功能提取出来,并尽量做到普适 ...