#ssm+jsp实现图片上传,以及解决一些常见问题
平常商业项目中不免要做文件上传,像用户发送的图片,头像的上传等,本文就以头像的上传更新来讲述一下
话不多说,直接开干
一、前端
jsp:
<span class="charactor" id="userHeader">
<input id="updateHeader" type="file" style="display: none" />
<img src="" alt="" id="userHead" class="img" onclick="updateHeader()">
</span>
jsp中 input标签当type="file"的时候,浏览器会把文件的内容连同form的所有字段格式化后传递到服务器,display:none能将浏览等字样隐藏,从而实现通过点击头像实现选择文件
css:
.img{
width: 120px;
height: 100px;
}
.charactor{
font-family: Algerian;
font-size: 20px;
font-style: normal;
}
js:
function updateHeader() {
$("#updateHeader").click();
var formData = new FormData();
var header_file = $("#updateHeader").get(0).files[0]
var phone = "1234"
formData.append("headerFile", header_file)
formData.append("userPhone", phone)
alert("xxx")
$.ajax({
url: "/updateUser/updateHeader.html",
type: "POST",
dataType: "json",
processData: false,
contentType: false,
data: formData,
success: function (data) {
// var header = eval(data)
// alert(header)
$("#userHead").attr("src", data)
},
error: function () {
alert("error")
}
})
}
formData对象能以key-value保存数据,在ajax的data中直接代替之前的单一传值,将formData传上去就行了,这里需要注意的是,服务器可能会出现TypeError: ‘append’ called on an object that does not implement interface FormData.的错误,是因为没有加上processData:false和contentType:false这两个option
这里有必要解释一下这个为什么processData要为false呢
processData 默认 true 用于对data参数进行序列化处理
大家都知道,data里面是传入的json形式的字符串,而不能转换Dom树的格式,所以一定将processData设置为false!
contentType 设置为 false 是为了避免 JQuery 对其操作,失去分界符,致使服务器不能正常解析文件。
二 后台
本文采用的ssm注解形式,后台接收图片常用的有两种形式,第一种是将图片转成二进制流进行保存图片,这里不详讲,有兴趣的朋友可以去查查。第二种呢是通过
1.springMVC配置
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="104857600" />
<property name="maxInMemorySize" value="4096" />
<property name="defaultEncoding" value="UTF-8"></property>
</bean>
对文件进行配置,为文件限定大小并将字符编码转成utf-8或其他格式
2.controller
@RequestMapping("updateHeader.html")
public void updateHeader(HttpServletRequest request,HttpServletResponse response,
@RequestParam(value = "headerFile")MultipartFile header
,@RequestParam(value = "userPhone") String phone){
//对头像文件进行重命名
String headerName = UUID.randomUUID().toString().replaceAll("-","");
//获取文件的后缀
String ext = FilenameUtils.getExtension(header.getOriginalFilename());
//获取地址加后边的静态资源文件夹的地址
String url = request.getSession().getServletContext().getRealPath("/static/imgs/head");
System.out.println(url);
//得到整个文件的url
String urlAll = url + "/" + headerName + "." + ext;
try {
//将header这个文件存放到urlAll的路径当中
header.transferTo(new File(urlAll));
} catch (IOException e) {
e.printStackTrace();
}
//获取整体服务器中文件地址
String url2 = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/static/imgs/head"+ "/" + headerName + "." + ext;
//将文件的路径存入数据库中
registIm.updateHeader(url2,phone);
response.setHeader("Content-type","text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
//通过google的gson将url解析成json格式传给前台,图片将通过地址来进行显示
Gson gson = new Gson();
String json = gson.toJson(url2);
try {
response.getWriter().write(json);
} catch (IOException e) {
e.printStackTrace();
}
}
这里呢代码有些臃肿,提供大体思路,先将文件重命名以防同名图片造成不便,然后将图片存入项目路径,然后将图片的路径存入数据库,然后返回给前端,前端拿到地址后可直接显示图片。
像dao层,service层,和mapper.xml等文件就不一 一讲述了,
欢迎各位大佬指教,相互学习,原创转载请说明出处,谢谢~