这里,我只想总结一下我一下午研究文件上传,图片上传功能的思考。也许花费了很多时间,但还是觉得比较值的。
以前一直听说过“项目使用的所有图片应该保存在图片服务器上,”一直看过这样的代码:Java后端由各种流组成的处理图片或着文件的方法。当时其实都是朦胧的,似懂非懂的样子。现在或许是有那么的一点理解了:当项目或者具体说页面中存在大量的图片时,页面的加载可能会很慢,这时,可能就需要使用一个独立的服务器来专门的读取这些图片了, 所以才有了图片服务器的说法。(或许是这样)。
图片上传功能的具体实现(当然文件也一样):
总的来说是这样的, 我们在页面上通过按钮获取到某张图片后,会显示在页面上(如果你需要的话),显示的可以是图片本身,或者是图片的名字。然后通过ajax,把图片传到了Java后台,(以什么格式我还不清楚),根据我这一下午的实践,MultipartFile ,这个类可以完全接收到前台传过来的图片数据。,这里也许有人会问, 传到后台干嘛呢。假设你的前端调用的不是你本项目的Java后台代码,而是另外一个接口Api项目的话, 那么,其实,这个APi项目就可以当作一个图片服务器了。额,这里仅仅是临时保存了图片而已,就页面而言,如果是表单,你还需要提交表单。那么表单提交时,你还会保存图片吗?应该是存图片在服务器上的地址吧。
MultipartFile 通过 MultipartFile .transferTo( new File()), 仅需要这步骤,就可以把图片存到服务器所在的电脑的任意一个盘或者路径里面。 其实这个很简单,难是难在 文件的创建。(坑了我很久),
new File("d:/test1/test2/test3/demo.png"), 类似要创建这样的 File文件时, 你要先判断demo.png 的父级路径是否存在,如果不存在则要先创建。否则你也许会报一个错误,“java.io.FileNotFoundException 拒绝访问”.
也许废话说了很多,下面直接上示例代码, 本实例代码亲测有效可用。本实例 前端采用layui + 后端 springMVC+MultipartFile
页面.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head>
<title>文件上传demo</title>
<%@include file="/comm/mytags.jsp" %>
</head>
<body>
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 30px;">
<legend>常规使用:普通图片上传</legend>
</fieldset>
<div class="layui-upload">
<button type="button" class="layui-btn" id="test1">上传图片</button>
<div class="layui-upload-list">
<img class="layui-upload-img" id="demo1">
<p id="demoText"></p>
</div>
</div>
</body>
<script>
layui.use(['form','upload'],function(exports) {
var form = layui.form;
var $ = layui.jquery;
var upload = layui.upload;
var token = "${param.token}";
var applicationCode= "${param.applicationCode}";
upload.render({
elem: '#test1'
,url: '${ctx}/demo/upload.do?token='+token+"&applicationCode="+applicationCode
,before: function(obj){
//预读本地文件示例,不支持ie8
obj.preview(function(index, file, result){
$('#demo1').attr('src', result); //图片链接(base64)
});
}
,done: function(res){
//如果上传失败
if(res.code > 0){
return layer.msg('上传失败');
}
//上传成功
}
});
});
</script>
</html>
后端代码:
@RequestMapping(value = "/upload")
@ResponseBody
public String upload( MultipartFile file, HttpServletRequest request) {
Calendar currTime = Calendar.getInstance();
String time = String.valueOf(currTime.get(Calendar.YEAR))+String.valueOf((currTime.get(Calendar.MONTH)+1));
String path ="d:"+File.separator+"img"+File.separator+time;
String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
suffix = suffix.toLowerCase();
if(suffix.equals(".jpg") || suffix.equals(".jpeg") || suffix.equals(".png") || suffix.equals(".gif")){
String fileName = UUID.randomUUID().toString()+suffix;
File targetFile = new File(path, fileName);
if(!targetFile.getParentFile().exists()){ //注意,判断父级路径是否存在
targetFile.getParentFile().mkdirs();
}
long size = 0;
//保存
try {
file.transferTo(targetFile);
size = file.getSize();
} catch (Exception e) {
e.printStackTrace();
}
JSONObject result = new JSONObject();
result.put("fileUrl", "/img/"+time+fileName);
result.put("url", "/img/"+time+fileName);
result.put("state", "SUCCESS");
result.put("title", fileName);
result.put("original", fileName);
result.put("type", suffix);
result.put("size", size);
return result.toString();
}else{
JSONObject result = new JSONObject();
result.put("ss", false);
result.put("msg", "格式不支持");
return result.toString();
}
}
注意: 前端代码,直接拿去使用的话,可能会有问题, 因为你们没有 token,applicatonCode两个参数。
另外,Java后端代码中, 考虑到多系统使用情况, 分隔符“/”"\", 统一使用了 File.seperator() 来代替。
这里仅仅是单个图片的上传,多个文件,多个图片一起上传的方法也许也是大同小异。