工做时遇到一个对轮播图管理的需求,开发过程遇到些问题,总算顺利解决,记录下来供你们参考。原项目是基于SSM框架搭建的,现将Ajax图片上传部分分享以下:html
说明:ajax
1. 传统的表单序列化,即经过$('#fm').serialize()能够对form表单进行序列化,从而将form表单中的全部参数传递到服务端,但该方法只能传递通常的参数,上传文件的文件流是没法被序列化并传递的。json
2. 本文采起的方式是经过FormData对象实现的。现在主流浏览器都开始支持一个叫作FormData的对象,有了这个FormData,咱们就能够轻松地使用Ajax方式进行文件上传了。数组
FormData是什么呢?
浏览器
XMLHttpRequest Level 2添加了一个新的接口FormData,利用
FormData对象,
咱们能够经过JavaScript用一些键值对来模拟一系列表单控件,咱们还可使用XMLHttpRequest的Send()方法来异步的提交这个"表单"。比起普通的ajax,使用FormData
的最大优势就是咱们能够异步上传一个二进制文件。全部主流浏览器的较新版本都已经支持这个对象了,好比Chrome 7+、Firefox 4+、IE 10+、Opera 12+、Safari 5+。
1.dao层代码缓存
<!--新增照片 -->服务器
<insert id="addImage" parameterType="Image">app
<!--自动生成id(string类型) -->框架
<selectKey keyProperty="id" resultType="string" order="BEFORE">异步
SELECTUUID()
</selectKey>
insertinto image(id,imgName,path,uploadTime,uploader,type,displayOrder)
values(#{id},#{imgName},#{path},#{uploadTime},#{uploader},#{type},#{displayOrder})
</insert>
2.service层没什么逻辑,代码在此省略
3.controller层代码
@RequestMapping("/imageManage")
public class ImageController {
@Autowired
private ImageService imageService;
// 新增轮播图片
@RequestMapping("/addImage")
@ResponseBody
public void addImg(
@RequestParam(value ="file", required =false) MultipartFile file,
@RequestParam(value ="uploader", required =false) String uploader,
HttpServletRequestrequest) {
String type =request.getParameter("type");
String order =request.getParameter("order");
Integer displayOrder =Integer.parseInt(order);
String DirectoryName ="/upload";
Image image =new Image();
if (uploader !=null) {
image.setUploader(uploader);
}
image.setUploadTime(DateUtil.DateToStr(DateUtil.yyyy_MM_dd_HH_mm_ss, new Date()));
image.setType(type);
//System.out.println("displayOrder"+ displayOrder.getClass().getName() + displayOrder);
String fileName =null;
if (file !=null) {
//取得当前上传文件的文件名称
String myFileName = file.getOriginalFilename();
//System.out.println("myfileName"+myFileName);
// System.out.println("文件名称"+file.getContentType());
//若是名称不为"",说明该文件存在,不然说明该文件不存在
if (myFileName.trim() !="") {
//得到图片的原始名称
String originalFilename = file.getOriginalFilename();
//System.out.println("originalFilename----"+originalFilename);
//得到图片后缀名称,若是后缀不为图片格式,则不上传
String suffix = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();
//得到上传路径的绝对路径地址(/upload)-->
String realPath = request.getSession().getServletContext().getRealPath("/" + DirectoryName);
// System.out.println(realPath);
//若是路径不存在,则建立该路径
File realPathDirectory =new File(realPath);
if (realPathDirectory ==null || !realPathDirectory.exists()) {
realPathDirectory.mkdirs();
}
//重命名上传后的文件名 111112323.jpg
String format ="yyyyMMddHHmmss";
SimpleDateFormat simpleDateFormat =new SimpleDateFormat(format);
fileName= simpleDateFormat.format(new Date()) + suffix;
//定义上传路径 .../upload/111112323.jpg
File uploadFile =new File(realPathDirectory +"\\" + fileName);
// System.out.println(uploadFile);
image.setImgName(originalFilename);
//保存
try {
file.transferTo(uploadFile);
}catch (Exception e) {
e.printStackTrace();
}
image.setPath(request.getContextPath()+ DirectoryName +"\\" + fileName);
Image image_1 =new Image();
image_1.setType(type);
//根椐类型查询
List<Image> list =imageService.getImageList(image_1);
if (list.size() != 0) {
//图片是满的就替换
if (list.size() == 4) {
for (Image image2 : list) {
if(image2.getDisplayOrder().equals(displayOrder)) {
imageService.delImage(image2);
}
}
image.setDisplayOrder(displayOrder);
imageService.addImage(image);
//图片没满就日后推移
}else {
for (Image image2 : list) {
if(!image2.getDisplayOrder().equals(displayOrder)){
image.setDisplayOrder(displayOrder);
}else {
image.setDisplayOrder(list.size()+1);
}
}
imageService.addImage(image);
}
}else {
image.setDisplayOrder(1);
imageService.addImage(image);
}
}
}
}
4.HTML代码
<div class="trd pic add">
<!-- enctype="multipart/form-data"是图片上传的基础,必须有 -->
<form id="fm" name="fm" enctype="multipart/form-data" method="post">
<div class="namezone">轮播图新增</div>
<div class="tablezoneclearfix">
<div class="left box">请添加图片</div>
<div class="left box">
<div class="imageBoxclearfix">
<input type="file" class="file" name="file"/>
<span class="red">图片需处理过</span>
</div>
</div>
<div class="left boxbtn">
展现顺序
<select name="order" id="order">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
<select name="type" id="type">
<option value="电脑">电脑</option>
<option value="手机">手机</option>
</select>
<input type="button" class="button" value="保存" id="save"/>
<input type="button" class="button" value="返回" id="back" onclick="history.go(-1)"/>
</div>
</div>
</form>
</div>
5.js代码
var addPic = {
//点击保存向后台发送保存的数据
save :function (userName) {
$("#save").click(function () {
$.ajax({
type:"POST",
url:"/HuaMuWebsite/imageManage/addImage?uploader="+userName,
data:new FormData($("#fm")[0]),//序列化表单值
async:false,
contentType:false,//必须有
processData:false,//必须有
error:function(request) {
alert("请求出错!");
},
success:function() {
$(window.parent.document).find("#iframe").attr("src",window.location.href="/HuaMuWebsite/admin/src/sliderCtrl.html?userName="+userName);
}
});
})
}
};
$(function () {
var userName=window.location.href;
var aa=userName.indexOf("=");
if( aa == -1)
return"";
userName=userName.substring(aa+1);
addPic.save(userName);
});
注意:contentType: false,
processData: false,
这两个参数是必须的。两者缺乏任何一个都会报错。
ajax方法参数老是记不住,在此顺便将ajax参数整理以下:
1)url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址。
2)type: 要求为String类型的参数,请求方式(post或get)默认为get。注意其余http请求方法,例如put和delete也可使用,但仅部分浏览器支持。
3)async: 同步仍是异步,要求为Boolean类型的参数,默认设置为true,全部请求均为异步请求。若是须要发送同步请求,请将此选项设置为false。注意,同步请求将锁住浏览器,用户其余操做必须等待请求完成才能够执行。
4)cache: 要求为Boolean类型的参数,默认为true(当dataType为script时,默认为false),设置为false将不会从浏览器缓存中加载请求信息。
5)data:要求为Object或String类型的参数,要发送到服务器的数据。若是已经不是字符串,将自动转换为字符串格式。get请求中将附加在url后。防止这种自动转换,能够查看下边的processData选项。对象必须为key/value键值对格式,例如{key1:"value1",key2:"value2"}转换为&key1=value1&key2=value2。若是是数组,JQuery将自动为不一样值对应同一个名称。例如{key:["value1","value2"]}转换为&key=value1&key=value2。
6)dataType: 要求为String类型的参数,预期服务器返回的数据类型。若是不指定,JQuery将自动根据http包mime信息返回responseXML或responseText,并做为回调函数参数传递。可用的类型以下:
xml:返回XML文档,可用JQuery处理。
html:返回纯文本HTML信息;包含的script标签会在插入DOM时执行。
script:返回纯文本JavaScript代码。不会自动缓存结果。除非设置了cache参数。注意在远程请求时(不在同一个域下),全部post请求都将转为get请求。
json:返回JSON数据。
jsonp:JSONP格式。使用JSONP形式调用函数时,例如myurl?callback=?,JQuery将自动替换后一个“?”为正确的函数名,以执行回调函数。
text:返回纯文本字符串。
7)success:要求为Function类型的参数,请求成功后调用的回调函数,有两个参数。
①由服务器返回,并根据dataType参数进行处理后的数据。
②描述状态的字符串。
function(data, textStatus){
//data多是xmlDoc、jsonObj、html、text等等
this; //调用本次ajax请求时传递的options参数
}
8)error:要求为Function类型的参数,请求失败时被调用的函数。该函数有3个参数,即XMLHttpRequest对象、错误信息、捕获的错误对象(可选)。ajax事件函数以下:
function(XMLHttpRequest,textStatus, errorThrown){
//一般状况下textStatus和errorThrown只有其中一个包含信息
this; //调用本次ajax请求时传递的options参数
}
9)contentType:要求为Boolean类型的参数,当发送信息至服务器时,内容编码类型默认为"application/x-www-form-urlencoded"。该默认值适合大多数应用场合。
10)processData:要求为Boolean类型的参数,默认为true。默认状况下,发送的数据将被转换为对象(从技术角度来说并不是字符串)以配合默认内容类型"application/x-www-form-urlencoded"。若是要发送DOM树信息或者其余不但愿转换的信息,请设置为false。
11)jsonp:要求为String类型的参数,在一个jsonp请求中重写回调函数的名字。该值用来替代在"callback=?"这种GET或POST请求中URL参数里的"callback"部分,例如{jsonp:'onJsonPLoad'}会致使将"onJsonPLoad=?"传给服务器。
12)username:要求为String类型的参数,用于响应HTTP访问认证请求的用户名。
13)password:要求为String类型的参数,用于响应HTTP访问认证请求的密码。
14)ifModified:要求为Boolean类型的参数,默认为false。仅在服务器数据改变时获取新数据。服务器数据改变判断的依据是Last-Modified头信息。默认值是false,即忽略头信息。
15)scriptCharset:要求为String类型的参数,只有当请求时dataType为"jsonp"或者"script",而且type是GET时才会用于强制修改字符集(charset)。一般在本地和远程的内容编码不一样时使用。
16)dataFilter:要求为Function类型的参数,给Ajax返回的原始数据进行预处理的函数。提供data和type两个参数。data是Ajax返回的原始数据,type是调用jQuery.ajax时提供的dataType参数。函数返回的值将由jQuery进一步处理。
function(data, type){
//返回处理后的数据
return data;
}
17)timeout: 要求为Number类型的参数,设置请求超时时间(毫秒)。此设置将覆盖$.ajaxSetup()方法的全局设置。
18)global:要求为Boolean类型的参数,默认为true。表示是否触发全局ajax事件。设置为false将不会触发全局ajax事件,ajaxStart或ajaxStop可用于控制各类ajax事件。
19)beforeSend:要求为Function类型的参数,发送请求前能够修改XMLHttpRequest对象的函数,例如添加自定义HTTP头。在beforeSend中若是返回false能够取消本次ajax请求。XMLHttpRequest对象是唯一的参数。
function(XMLHttpRequest){
this; //调用本次ajax请求时传递的options参数
}
20)complete:要求为Function类型的参数,请求完成后调用的回调函数(请求成功或失败时均调用)。参数:XMLHttpRequest对象和一个描述成功请求类型的字符串。
function(XMLHttpRequest, textStatus){
this; //调用本次ajax请求时传递的options参数 }