文件上传的用处很大,好比上传头像什么的,都须要文件上传。javascript
今天我刚写完文件上传,大大小小的各类bug,我也是很苦恼。可是还好终于都写完了。来博客分享一下。css
最重要的就是Multiparfile 和 jesyf实现跨域!html
须要的jar包:前端
文件上传:com.springsource.org.apache.commons.fileupload-1.2.0.jarjava
文件的读写:com.springsource.org.apache.commons.io-1.4.0.jarmysql
因为是跨服务器上传,这里是经过jersey实现的:jquery
jersey-client-1.18.jarweb
jersey-core-1.18.jarajax
在springmvc配置文件中,加上配置:spring
<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>
db.properties配置文件:修改url
url=jdbc\:mysql\:///mybatis?useUnicode=true&characterEncoding=utf8
去tomcat 修改jersey服务:
咱们模拟建立一个图片服务器,在web下建立一个存放图片的地方(upload),而后更换端口号(别跟主工程同样就行)
接下来运行工程,自浏览器打开的网页别关。
而后咱们在建立一个要获取文件的工程。这个工程必须是一个SSM。能够运行的。
建立一个list.jsp(显示查询出来的数据)
建立一个UpdateUser.jsp(修改界面)
Mapper和Service层,本身写就能够了。就是简单的一个修改,和查询。
数据库的表能够按照个人PO类进行建立。也能够用本身的。(图片的字段设置null)!
这个是PO类。
public class Items {
private Integer id;
private String name;
private Float price;
private String pic;
private String createtime;
private String detail;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name == null ? null : name.trim();
}
public Float getPrice() {
return price;
}
public void setPrice(Float price) {
this.price = price;
}
public String getPic() {
return pic;
}
public void setPic(String pic) {
this.pic = pic == null ? null : pic.trim();
}
public String getCreatetime() {
return createtime;
}
public void setCreatetime(String createtime) {
this.createtime = createtime;
}
public String getDetail() {
return detail;
}
public void setDetail(String detail) {
this.detail = detail == null ? null : detail.trim();
}
@Override
public String toString() {
return "Items{" +
"id=" + id +
", name='" + name + '\'' +
", price=" + price +
", pic='" + pic + '\'' +
", createtime=" + createtime +
", detail='" + detail + '\'' +
'}';
}
}
MultipartHttpServletRequest 用于根据name名称获取多部件请求对象
CommonsMultipartFile 多部件请求对象,该对象能够获取到file文件对象信息,用于上传文件作准备
PrintWriter 对象能够将json对象回传给ajax
步骤:
1 设置方法三个参数
2 根据input的name名获取CommonsMultipartFile 对象
3 获取文件上传流
4 拼接文件名(毫秒时间+2个随机数)
5 获取源文件扩展名,后缀
6 建立上传服务器文件完整路径 Commons.PIC_HOST+"/upload/"+fileNameStr+suf
7 建立jesy服务器Clien对象,实现跨域上传
8 开始上传 resource.put(String.class,bytes);
9 拼接相对文件路径,用于存储到数据库中
10 将完整路径与相对路径拼接为json格式 String result="{\"fullPath\":\""+fullPath+"\",\"relativePath\":\""+relativePath+"\"}";
11 回传给ajax printWriter.print(result);
这个是我Controller层:
@RequestMapping(value = "uploadPic",method = RequestMethod.POST)
// MultipartHttpServletRequest 用于根据name名称获取多部件请求对象
public void uploadPic(MultipartHttpServletRequest request, String fileName, PrintWriter printWriter){
CommonsMultipartFile cmf = (CommonsMultipartFile) request.getFile(fileName);
// 获取文件上传流
byte[] bytes = cmf.getBytes();
String fileNameStr = "";
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
fileNameStr = sdf.format(new Date());
System.out.println("时间戳"+fileNameStr);
Random random = new Random();
for (int i = 0; i < 3; i++) {
fileNameStr +=random.nextInt(10);
}
// 获取文件扩展名
String originalFilename = cmf.getOriginalFilename();
String suf = originalFilename.substring(originalFilename.lastIndexOf("."));
System.out.println("获取文件扩展名"+suf);
// 建立jesyf服务器,实现跨域上传文件
Client client = new Client();
WebResource resource = client.resource(Commons.PIC_HOST+"/upload/"+fileNameStr+suf);
resource.put(String.class,bytes);
// 拼接图片完整路径
String fullPath = Commons.PIC_HOST+"/upload/"+fileNameStr+suf;
String relativePath = "/upload/"+fileNameStr+suf;
String result="{\"fullPath\":\""+fullPath+"\",\"relativePath\":\""+relativePath+"\"}";
System.out.println("完整路径"+result);
System.out.println("完美路径"+relativePath);
// 向页面输出一个json对象
printWriter.print(result);
}
这个页面是显示我查询出来数据的jsp页面。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%--java提供的jstl标签库,用于前端引入java变量--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--date类型转换为字符串--%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%--<script type="text/javascript" src="/js/jquery.js"></script>--%>
<%--<script type="text/javascript" src="/js/jquery.form.js"></script>--%>
<script src="https://cdn.bootcss.com/jquery/2.2.3/jquery.js"></script>
<%--<script type="text/javascript" src="/js/jquery.form.js"></script>--%>
<script src="https://cdn.bootcss.com/jquery.form/3.49/jquery.form.js"></script>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>欢迎使用list回显</title>
</head>
<body>
配置公共路径:
再没上传图片以前,picPath是空的。(是为了在上传以后,你会发现数据库已经有了图片路径,到那时页面没显示,就须要这句话。)
<c:set var="picPath" value="http://127.0.0.1:8082/"></c:set>
<table border="2px" cellpadding="0px" cellspacing="0px" width="1000px" >
<tr>
<th>编号</th>
<th>姓名</th>
<th>价格</th>
<th>详情</th>
<th>商品图片</th>
<th>日期</th>
</tr>
<c:forEach items="${itemsList}" var="items">
<tr>
<td>${items.id}</td>
<td>${items.name}</td>
<td>${items.price}</td>
<td>${items.detail}</td>
<td><img src="${picPath}${items.pic}" alt="" width="100" height="100"></td>
<td>
${items.createtime}
</td>
<td>
<a href="${pageContext.request.contextPath}/upload/updateUser.do?id=${items.id}&picPath=${picPath}">修改</a>
</td>
<td>
<a href="javascript:void(0);" onclick="btnAction(${user.id})">删除</a>
</td>
</tr>
</c:forEach>
</table>
</body>
</html>
ajax使用的是:
jQuery Form插件是一个优秀的Ajax表单插件,能够很是容易地、无侵入地升级HTML表单以支持Ajax。
jQuery Form有两个核心方法 – ajaxForm() 和 ajaxSubmit(), 它们集合了从控制表单元素到决定如何管理提交进程的功能
使用JQuery的$.ajax()会报错。
若是使用$.ajax()请求,则提交的Request类型最终为RequestFacade,而不是MultipartHttpRequest
这个是个人修改界面:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<title>Title</title>
<%--<script type="text/javascript" src="/js/jquery-1.8.3.min.js"></script>--%>
<script src="https://cdn.bootcss.com/jquery/2.2.3/jquery.js"></script>
<%--<script type="text/javascript" src="/js/jquery.form.js"></script>--%>
<script src="https://cdn.bootcss.com/jquery.form/3.49/jquery.form.js"></script>
<script type="text/javascript">
function submitImgSize1Upload(){
// alert('你是猪吗'); 验证是否走了点击事件
var option={
url:'${pageContext.request.contextPath }/upload/uploadPic.do',
type:'POST',
dataType:'text',
data:{
fileName : 'imgSize1File' 将选取的图片路径传到后台进行处理。
},
success:function(data){
alert(data);
//把json格式的字符串转换成json对象
var jsonObj = $.parseJSON(data);
// 经过input标签设置的ID,把图片路径fu gei
//返回服务器图片路径,把图片路径设置给img标签(显示修改页面的图片)
$("#imgSize1ImgSrc").attr("src",jsonObj.fullPath);
//数据库保存相对路径,在图片的input标签内加上Id,把imgSize1写到id内
//把路径传到后台,添加到数据库中。
$("#imgSize1").val(jsonObj.relativePath);
},
};
//拿到form表单对象,提交表单
$("#itemForm").ajaxSubmit(option);
}
</script>
</head>
<body>
这个属性是文件上传必须用到的
<form id="itemForm" action="${pageContext.request.contextPath}/upload/updateById.do" method="post" enctype="multipart/form-data">
<input type="hidden" name="id" value="${items.id}">
姓名:
<input type="text" name="name" value="${items.name}">
<br>
价格 : <input type="text" name="price" value="${items.price}">
<br>
描述 : <input type="text" name="detail" value="${items.detail}">
<br>
商品图片: <img id='imgSize1ImgSrc' src='${picPath}${items.pic}' height="100" width="100" /><br>
图片路径: <input id="imgSize1" type="text" name="pic" value="${items.pic}"><br>
日期 :<input type="text" name="createtime" value="${items.createtime}"><br>
<input type='file' id='imgSize1File' name='imgSize1File' class="file" onchange='submitImgSize1Upload()'/>
<input type="submit" value="提交">
</form>
</body>
</html>
这个是Maven版本的须要导入的依赖: