Jquery插件AjaxUpload实现文件上传功能时无需创建form表单,即可实现Ajax方式的文件上传,当然根据需要也可以创建form表单。
springmvc.xml配置CommonsMulitpartResolver
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 最大图片大小不超过5M -->
<property name="maxUploadSize" value="#{5*1024*1024}"/>
<!-- 编码 -->
<property name="defaultEncoding" value="UTF-8"/>
</bean>
image-upload.html
<html lang="en">
<head>
<meta charset="UTF-8">
<title>图片上传title>
上传图片: <input type="file" id="upload" />
head>
<body>
<script src="plugins/jquery/jquery.min.js">script>
<script src="plugins/ajaxupload/ajaxupload.js">script>
<script src="dist/js/upload.js">script>
body>
html>
对于jquery.min.js和ajaxupload.js文件文章末尾链接
upload.js
$(function(){
new AjaxUpload('#upload', {
// 服务器端位置
action: 'images',
// 文件上传名字
name: 'imageFile',
// 选定后立即提交
autoSubmit: true,
// 期望从服务器返回的数据类型。仅在将json数据用作响应时有用
responseType: "json",
// 上传文件前触发回调, false表示取消上传
onSubmit: function (file, extension) {
if (!(extension && /^(jpg|jpeg|png|gif)$/.test(extension.toLowerCase()))) {
alert('只支持jpg、png、gif格式的图片!', {
icon: "error",
});
return false;
}
},
//文件上传完成后触发
onComplete: function (file, r) {
if (r.resultCode == 200) {
alert("上传成功");
} else {
alert(r.message);
}
}
});
})
PictureUploadController
建议自己DEBUG走一趟观察各个语句的情况
@Controller
@RequestMapping("/images")
public class PictureUploadController {
/**
* @return
* @throws Exception
*/
@RequestMapping(value = "", method = RequestMethod.POST)
@ResponseBody
// 接收参数必须有一个MultipartFile对象,以及request获取项目路径
public Result upload(HttpServletRequest request, @RequestParam("imageFile") MultipartFile imageFile) throws IOException {
// 获取当前项目路径
ServletContext sc = request.getSession().getServletContext();
// 获取要下载到指定目录的位置,即tomcat目录下的upload文件夹下
String realPath = sc.getRealPath("/upload");
// 如果没有该路径,则创建
File file = new File(realPath);
if(!file.exists()) {
file.mkdir();
}
// 先获取下载图片的原始名称,再截取后缀名字
String type = imageFile.getOriginalFilename().substring(imageFile.getOriginalFilename().lastIndexOf(".") + 1, imageFile.getOriginalFilename().length());
// 防止图片重名冲突覆盖
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
Random r = new Random();
String imgName = "";
// 如果后缀匹配成功,则改掉上传图片名字,防止图片重名冲突覆盖,并且只支持jpg、png、jpeg、gif图片格式
if ("jpg".equals(type)) {
imgName = sdf.format(new Date()) + r.nextInt(100) + ".jpg";
} else if ("png".equals(type)) {
imgName = sdf.format(new Date()) + r.nextInt(100) + ".png";
} else if ("jpeg".equals(type)) {
imgName = sdf.format(new Date()) + r.nextInt(100) + ".jpeg";
} else if ("gif".equals(type)) {
imgName = sdf.format(new Date()) + r.nextInt(100) + ".gif";
} else {
return null;
}
// 输入流(inputstream)转为输出流(outputstream) 存储图片
// 输出流(java程序输出数据->文件)
// 第一个参数:文件 第二个参数: 文件二进制字节数组
FileUtils.writeByteArrayToFile(new File(realPath, imgName), imageFile.getBytes());
// 封装成功数据返回json格式
Result result = ResultGenerator.genSuccessResult();
// 保存的是图片的位置(图片我们都是存储图片的位置)
result.setData(realPath + imgName);
return result;
}
}
效果展示
图片是保存在tomcat目录下的upload文件夹下,所以每次重新启动tomcat后,图片会消失,如果需要永久保存,只要把上面controller层代码最后的new File()里面第一个参数文件路径改为其它盘符位置即可,数据库保存图片位置(这里就不参演示保存永久情况)
如果不会vsftpd搭建FTP实现图片上传(比如我尝试了N次仍然不行,决定暑假后再搞搞),
那么自己的项目部署到阿里云上,其它方法都有点复杂,由于没有时间去尝试,所以还是选择在远程即阿里云上的tomcat下实现图片保存,这里会遇到几个坑的地方,比如没用jersey的话,每次上传完图片后就消失, 403 则是conf/web.xml中没有添加readonly为false的配置
maven依赖
spring的一些包以及fileupload和io包和jerset相关包
<dependency>
<groupId>commons-iogroupId>
<artifactId>commons-ioartifactId>
<version>${commons-io.version}version>
dependency>
<dependency>
<groupId>commons-fileuploadgroupId>
<artifactId>commons-fileuploadartifactId>
<version>${commons-fileupload.version}version>
dependency>
<dependency>
<groupId>com.sun.jerseygroupId>
<artifactId>jersey-clientartifactId>
<version>1.19version>
dependency>
<dependency>
<groupId>com.sun.jerseygroupId>
<artifactId>jersey-coreartifactId>
<version>1.19version>
dependency>
修改远程服务器tomcat的配置,找到web.xml进行修改
可以看到默认情况下当我们进行put或者delete操作的时候,服务器是拒绝访问的,所以想向服务器上传文件必须将readonly
属性设置为false
所以添加readonly参数为false
<servlet>
<servlet-name>defaultservlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServletservlet-class>
<init-param>
<param-name>debugparam-name>
<param-value>0param-value>
init-param>
<init-param>
<param-name>readonlyparam-name>
<param-value>falseparam-value>
init-param>
<init-param>
<param-name>listingsparam-name>
<param-value>trueparam-value>
init-param>
<load-on-startup>1load-on-startup>
servlet>
在tomcat服务器上创建文件存储目录upload
(自己在项目中手动创建,这样你部署项目上去,同样也会创建好upload文件夹的)
Controller代码
@Controller
@RequestMapping("/images")
public class PictureUploadController {
/**
* @return
* @throws Exception
*/
@RequestMapping(value = "", method = RequestMethod.POST)
@ResponseBody
public Result upload(HttpServletRequest request, @RequestParam("file") MultipartFile file) throws IOException {
// 配置linux下的tomcat访问前缀(我项目是放在远程tomcat的ROOT下的)
String path = "http://ip地址:8080/upload/";
String type = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1, file.getOriginalFilename().length());
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
Random r = new Random();
String imgName = "";
if ("jpg".equals(type)) {
imgName = sdf.format(new Date()) + r.nextInt(100) + ".jpg";
} else if ("png".equals(type)) {
imgName = sdf.format(new Date()) + r.nextInt(100) + ".png";
} else if ("jpeg".equals(type)) {
imgName = sdf.format(new Date()) + r.nextInt(100) + ".jpeg";
} else if ("gif".equals(type)) {
imgName = sdf.format(new Date()) + r.nextInt(100) + ".gif";
} else {
return null;
}
// 拼接存储路径
String url = path + imgName;
// 要在不同主机上上传文件,所以不能直接通过流的方式来写
// 需要通过webService来完成,这里借助Jersey来完成
// jersy包下的,这个对象可以生成创建一个网络资源
Client client = new Client();
// 生成web资源
WebResource resource = client.resource(url);
// 通过网络资源往指定位置放
resource.put(String.class, file.getBytes());
Result result = ResultGenerator.genSuccessResult();
// 存储的是图片的位置,即tomcat目录下的upload文件下,这样数据库也保存此路径
result.setData("/upload/" + imgName);
return result;
}
}
jquery.min.js
ajaxupload.js