功能:点击图片,进行图片的选择,然后预览,再存到数据库中。
插件:ajaxFileUpload.js
插件下载路径(网盘,因为CSDN上已有该资源,所以上传不上去):
https://pan.baidu.com/s/1LlwSFqxfPQjTXg5JTwaGCA(无需提取码)
用到的软件:eclipse , navicat premium 12
方法:
(1)html页面
<div class="col-sm-12">
<div>
<input type="hidden" id="hidden" value="$!{photos.id}">
<img src="$!{photos.purl}" id="sign" name="photoId"
height="300px" width="500px" style="border: 1px solid #e5e6e7; margin: 16px;
cursor: pointer;" onclick="fileSelect()">
</div>
<input type="file" name="fileToUpload" id="fileToUpload"
onchange="fileSelected()" >
</div>
页面解释:
· 隐藏的文本域,是用来接收传过来的数据的ID(与图片上传无关),关乎的是将图片存到那一条记录中(我的数 据库是两张关联的表,其中一张表的外键是图片表)
· <img> 里面的src,是从数据库中查出来的路径(先存图片,再将信息传到前端,将其显示出来)sty le属性是根 据项目需求来写的,大家可以不用理会。
· 第二个<input>, type属性一定是file,name和id是自定义的
(2)js语句(可以提取出来或者放在html中)
function fileSelect() {
document.getElementById("fileToUpload").click();
}
//file_id
function fileSelected() {
var id = document.getElementById("id").value;
// 文件选择后触发函数
$.ajaxFileUpload({
url:"要跳转的路径"+"?id="+id,//需要链接到服务器地址
secureuri:false, //是否启用安全提交,默认为false
fileElementId:"fileToUpload",//文件选择框的id属性
dataType: 'json', //json
allowType:'jpg,jpeg,png,JPG,JPEG,PNG',
success: function (data) {
var msg = JSON.parse(data.msg);
$("#sign").prop("src",msg); //去替换掉img标签里src里的值
},error:function(XMLHttpRequest, textStatus, errorThrown){
alert('上传失败!');
}
});
}
页面解释:
· 当用户点击图片的时候,触发了fileSelect()函数,进入到这个函数后,执行函数代码,然后触发了 fileSelected()函数。
· 因为我需要传参,就用到var id
· $.ajaxFileUpload({}),这个就需要引入ajaxfileupload.js,讲真,非常好用的一个插件,能传图片能传文件,强烈 推荐。
· 在存入数据库之后(后续会写),会将信息返回过来,如果成功的话,我们就可以得到图片的路径,然后利用 $().prop(),进行数值的替换,需要注意的是jquery在高版本之后,就不用$().attr()了
· var msg = JSON.parse(data.msg);这里是将对象序列化,将接收到的JSON字符串转为对象使用。
(3)Java代码
①service中
public String savePhoto(HttpServletRequest request) {
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
String fileName = "";
String uploadPath = "/static/img/"; //路径是写死的,本来不用,但是连接文件名的时候,
少了一个“/”,这里就偷个懒写死了。
String path = request.getSession().getServletContext().getRealPath("WEB-
INF/static/img/");
File uploadPathFile = new File(path);
if (!uploadPathFile.exists()) { //如果路径不存在,就去创建
uploadPathFile.mkdirs();
}
String realPath = "";
//循环所有的文件名
for (Iterator it = multipartRequest.getFileNames(); it.hasNext();) {
String key = (String) it.next();
MultipartFile mulfile = multipartRequest.getFile(key);
fileName = mulfile.getOriginalFilename(); //文件原始名
path = path+"/";
File file = new File(path + fileName);
try {
mulfile.transferTo(file);//将文件写入磁盘中,强烈推荐
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
realPath = uploadPath+fileName; // 路径/文件名
return realPath;
}
② controller中
public String fileUpload( HttpServletRequest request,Long id) {
JsonResult js = new JsonResult();
//需要往数据库中保存
String realPath = fileService.savePhoto(request);
//图片名
String pname="";
//图片ID
Long pid = 1L;
String[] names = realPath.split("/");
pname = names[names.length-1];//获取文件名称最笨的办法
Photos p = new Photos();//需要一个实体类,属性为:ID,路径,名称等
boolean flag = false;
//获取图片中的所有信息,我用了mybatis-plus插件,写法会简单一些,否则得自己写sql
List<Photos> photoList = photoService.selectList(new EntityWrapper<Photos>(p));
//根据图片名判断是否存在
for (Photos photos : photoList) {
if(photos.getPname().equals(pname)) {
pid = photos.getId();
flag = true;
break;
}
}
//如果图片不存在,我们选择插入图片信息
if(flag == false) {
p.setPname(pname);
p.setPurl(realPath);
//insert方法mybatis-plus插件提供了,没用这个插件,大家要手写sql语句
photoService.insert(p);
//这里还要获取图片id,是为了传给前端,去判断我们需要预览的是哪个id的路径
pid = p.getId();
}
//这里是反序列化,大家可以用别的方式
js.setSuccess(true);
js.setMsg(JSONObject.toJSONString(realPath));
return JSONObject.toJSONString(js);
}
如果框架不同,用的插件不同,其实不用担心,核心代码是一样的,总的来说,进行图片的上传,需要理解的是:
ajaxFileUpload.js , IO流, 序列化和反序列化
结果图:
注意,大家看到的“点击图片上传”其实是一张图片,黑字白底的图片。 可以在上面任意一个地方进行点击,点击之后,会出现
然后随便选一张图片,点击打开,然后就可以预览了(已提交)
为什么说已经提交了呢,大家可以翻一下前面的,点击图片之后,我们就走了$.ajaxFileUpload的路径,走到了controller方法。
哈哈,总结完毕!
………………更新……………………
onchang()是只触发一次,所以在$.ajaxFileUpload()里面找到session: 在这里面加上一句:
$("#fileToUpload").prop("onchange",fileSelected());
这样就可以进行多次的上传,否侧,只能上传一次