我之前就写过一篇博客记录SpringMVC实现文件上传功能,
但是那篇博客文件上传的位置不符合我的要求,而且回显也不方便,我想上传到本地磁盘的其他文件夹,以图片为例,如 E:\upload\photo。
要实现这种效果,需要给tomcat配置虚拟路径,我这次使用的是eclipse
1.在左边项目列表找到server
修改server.xml,在<Host></Host>标签里添加
<Context docBase="E:\upload\photo" path="/photo" reloadable="true"/>
docBase为文件系统目录,path为映射目录。
也可以在控制台双击tomcat,点击modules
点击add external web module来添加,效果和上面那种方法一样。
2.找到tomcat安装目录下的conf/server.xml,添加上面一样的配置
有些人说第二步不做也可以有用,反正我不行
完成后启动tomcat,输入映射地址+文件名,就可以访问了
-------------------------------------------------------------------------------------------------------
在以上配置的基础上,我们来实现用户更换头像,并将头像保存到数据库,在前台显示的功能
贴一次完整的代码,方便自己下次使用
首先我有个User,其他属性不重要,重点是有个photo属性来保存图片地址
package com.mqb.bean;
import java.util.Date;
import org.springframework.stereotype.Component;
@Component
public class User {
private Integer id;
private String name;
private String password;
private String salt;
private Integer hashiterations;
private Boolean islock;
private String staffNumber;
private String email;
private String photo;
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 String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password == null ? null : password.trim();
}
public String getSalt() {
return salt;
}
public void setSalt(String salt) {
this.salt = salt == null ? null : salt.trim();
}
public Integer getHashiterations() {
return hashiterations;
}
public void setHashiterations(Integer hashiterations) {
this.hashiterations = hashiterations;
}
public Boolean getIslock() {
return islock;
}
public void setIslock(Boolean islock) {
this.islock = islock;
}
public String getStaffNumber() {
return staffNumber;
}
public void setStaffNumber(String staffNumber) {
this.staffNumber = staffNumber == null ? null : staffNumber.trim();
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email == null ? null : email.trim();
}
public String getPhoto() {
return photo;
}
public void setPhoto(String photo) {
this.photo = photo == null ? null : photo.trim();
}
}
UserService
public interface UserService {
Integer updateUser(User user);
}
Impl
package com.mqb.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.mqb.bean.User;
import com.mqb.dao.UserDao;
import com.mqb.service.UserService;
@Service
public class UserServiceImpl implements UserService {
@Autowired
UserDao userDao;
public Integer updateUser(User user) {
return userDao.updateUser(user);
}
}
UserMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mqb.dao.UserDao">
<update id="updateUser" parameterType="com.mqb.bean.User">
update user set name=#{name},password=#{password},email=#{email},photo=#{photo} where id=#{id}
</update>
</mapper>
Controller,这里的name和email无关紧要,
@RequestMapping(value="/testUpdate",method=RequestMethod.POST)
@ResponseBody
public Msg testUpdate(
@RequestParam("name")String name,
@RequestParam("email")String email,
MultipartFile uploadFile,
HttpServletRequest request
) throws IllegalStateException, IOException {
// tomcat配置的虚拟路径
String realPath="E:\\upload\\photo\\";
String virtualPath="/photo/";
//获取原始图片的拓展名
String originalFilename = uploadFile.getOriginalFilename();
//新的文件名字,使用uuid随机生成数+原始图片名字,这样不会重复
String newFileName = UUID.randomUUID()+originalFilename;
//封装上传文件位置的全路径,就是硬盘路径+文件名
File targetFile = new File(realPath,newFileName);
//使用MultipartFile接口中的方法,把本地文件上传到已经封装好的文件位置的全路径就是上面的targetFile
uploadFile.transferTo(targetFile);
//将图片位置赋值给user的photo属性
User current=(User) request.getSession().getAttribute("user");
current.setPhoto(virtualPath+newFileName);
current.setName(name);
current.setEmail(email);
if(!(userService.updateUser(current)>0)) {
return Msg.fail();
}
return Msg.success();
}
jsp+jq,这里的filebox使用的是easyUI的样式
<table style="padding:100px">
<tr id="preview_tr">
<td class="td-marked"></td>
<td class="td-content">
<div id="Imgdiv">
<img id="Img" src="<shiro:principal property='photo'></shiro:principal>" width="100px" height="100px" style="board:1px solid black"/>
</div>
</td>
</tr>
<tr>
<td class="td-marked"></td>
<td class="td-content" id="file_td">
<div>
<input id="chooseFile" name="file" style="width:300px"/>
<p style="color: #c6c6c6;margin-top: 5px;">请选择一张图片</p>
</div>
</td>
</tr>
</table>
<script type="text/javascript">
$(function(){
$('#chooseFile').filebox({
buttonText: '选择文件',
buttonAlign: 'left',
accept: "image/gif,image/bmp,image/jpeg,image/jpg,image/png",
onChange: function (e) {
change_photo()
}
})
function change_photo() {
PreviewImage($("input[name='file']")[0], 'Img', 'Imgdiv');//传入绑定的文本框,图片、图片div
}
//焦点图片预览
function PreviewImage(fileObj,imgPreviewId,divPreviewId) {
var allowExtention = ".jpg,.bmp,.gif,.jpeg,.png";//允许上传文件的后缀名document.getElementById("hfAllowPicSuffix").value;
var extention = fileObj.value.substring(fileObj.value.lastIndexOf(".") + 1).toLowerCase();
if (allowExtention.indexOf(extention) > -1) {
if (fileObj.files) {//HTML5实现预览,兼容chrome、火狐7+等
if (window.FileReader) {
var reader = new FileReader();
reader.onload = function (e) {
// var tempDivPreview=document.getElementById(divPreviewId);
// tempDivPreview.style.display="block";
document.getElementById(imgPreviewId).setAttribute("src", e.target.result);
console.log(e.target.result);
}
if(fileObj.files[0]) {
reader.readAsDataURL(fileObj.files[0]);
}
}
} else {
document.getElementById(imgPreviewId).setAttribute("src", fileObj.value);
}
} else {
alert("仅支持" + allowExtention + "为后缀名的文件!");
fileObj.value = "";//清空选中文件
fileObj.outerHTML = fileObj.outerHTML;
}
}
$("#submit").click(function(){
var formdata=new FormData();
var f=$("input[name='file']")[0].files[0];
formdata.append("uploadFile",f);
formdata.append("name",$("input[name='name']").val());
formdata.append("email",$("input[name='email']").val());
console.log(f);
$.ajax({
type:'post',
url:'testUpdate',
data:formdata,
contentType: false,
processData: false,
success:function(){
alert("success");
},
error:function(){
alert("error");
}
})
})
})
</script>
----------------------------------------------------------------
大致的代码就是这样
比如我选择了这张图片,提交之后可以在控制输出图片实际保存位置和数据库里保存的位置
实际:E:\upload\photo\0f7413ad-010a-447a-aad6-fdfc1485762cprop_type_1.png
数据库:/photo/0f7413ad-010a-447a-aad6-fdfc1485762cprop_type_1.png
在前台显示时只要把User的photo取出来就可以显示了
-------------------------------------------------------------------------
对于图片的保存我们也可以进行一些优化,如文件名把中间的-去掉,按照上传日期不同添加文件夹什么的。看各自需要了