springmvc的文件上传
本身支持文件上传,所以我们要开启文件上传,
文件上传: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
导入依赖包
文件服务器
新建专门用来存放上传文件的工程,作为文件服务器
创建Upload文件夹
配置文件服务tomcat端口号与主项目tomcat端口号不同
ssm项目中
springmvc.xml文件中
< !-- 文件上传解析器 -->
< bean id=“multipartResolver” class=“org.springframework.web.multipart.commons.CommonsMultipartResolver”>
< /bean>
id必须是id=“multipartResolver”
jdbc.properties
配置数据库编码
jdbc.url = jdbc:mysql:///mybatis?useUnicode=true&characterEncoding=utf8
前端jsp页面
ajax使用的是
jQuery Form插件是一个优秀的Ajax表单插件,可以非常容易地、无侵入地升级HTML表单以支持Ajax。
jQuery Form有两个核心方法 – ajaxForm() 和 ajaxSubmit(), 它们集合了从控制表单元素到决定如何管理提交进程的功能
使用JQuery的$.ajax()会报错
如果使用$.ajax()请求,则提交的Request类型最终为RequestFacade,而不是MultipartHttpRequest
控制器根据input的name值imgSize1File找到图片对象
完整代码:
<script type="text/javascript" src="/js/jquery-1.8.3.min.js"></script>
<script type="text/javascript" src="/js/jquery.form.js"></script>
<script type="text/javascript">
function submitImgSize1Upload(){
var option={
type:'POST',
url:'${pageContext.request.contextPath }/upload/uploadPic.do',
dataType:'text',
data:{
fileName : 'imgSize1File'
},
success:function(data){
alert(data);
//把json格式的字符串转换成json对象
var jsonObj = $.parseJSON(data);
//返回服务器图片路径,把图片路径设置给img标签
$("#imgSize1ImgSrc").attr("src",jsonObj.fullPath);
//数据库保存相对路径
$("#imgSize1").val(jsonObj.relativePath);
}
};
//拿到form表单对象,提交表单
$("#itemForm").ajaxSubmit(option);
}
</script>
<img id='imgSize1ImgSrc' src='${picPath }${item.pic }' height="100" width="100" />
<input type='file' id='imgSize1File' name='imgSize1File' class="file" onchange='submitImgSize1Upload()' />
控制器
新建UploadController
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("/upload")
public class UploadController {
@RequestMapping(“uploadPic”)
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());
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("."));
// 创建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+"\"}";
// 向页面输出一个json对象
printWriter.print(result);
}
}
1 由于要获得上传的文件,所需参数要有request对象和文件的名称fileName,ajax需要回显图片,需要PrintWriter
2 由于上传的文件是流类型直接使用request对象无法获得.需要把request对象强转为多部件请求对象MultipartHttpServletRequest ,然后就可以通过文件名称来获得。至于为何可以强转为多部件请求对象MultipartHttpServletRequest ,是因为我们是使用ajax提交表单,根本没使用enctype.
3 由于文件名可能会出现重名,所以我使用当前时间+5个随机数作为新图片的文件名称
拼接json数据格式必须是{“”:””}
key与value都要用双引号串引起来
String result="{“fullPath”:""+fullPath+"",“relativePath”:""+relativePath+""}";
成功之后,前端页面提示下面格式才正确
常见问题
报错 说jersey服务不能用,上传的路径不对
com.sun.jersey.api.client.UniformInterfaceException
修改tomcat配置
将图片回显到列表中
<c:set var=“picPath” value=“http://127.0.0.1:8082/”></c:set>
这句很关键
我们接下来是想将图片回显示在商品列表中
查看数据库,发现已经存在了上传的图片路径
在itemsList.jsp文件中配置上传图片的公共路径
<c:set var=“picPath” value=“http://127.0.0.1:8082/”></c:set>
下面是在jsp代码中设置img标签
成功
同样需要在edititem.jsp文件中配置set路径
设置img标签路径
使用@ResponseBody
需要引入 Jackson相关jar包
ajax
Maven版的实现需要设置如下