跨域文件上传

文件上传的用处很大,比如上传头像什么的,都需要文件上传。

今天我刚写完文件上传,大大小小的各种bug,我也是很苦恼。但是还好终于都写完了。来博客分享一下。

最重要的就是Multiparfile 和 jesyf实现跨域!

 

需要的jar包:

文件上传:com.springsource.org.apache.commons.fileupload-1.2.0.jar

文件的读写:com.springsource.org.apache.commons.io-1.4.0.jar

由于是跨服务器上传,这里是通过jersey实现的:

jersey-client-1.18.jar

jersey-core-1.18.jar

 

在springmvc配置文件中,加上配置:

<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版本的需要导入的依赖:

 

 

posted @ 2018-11-21 19:02  不忘﹑  阅读(5432)  评论(0编辑  收藏  举报