在写javaweb的项目时免不了用户登录,为了用户体验问题那么头像是必不可少的。Mysql中是可以直接存储图片的,但是过多的图片会导致数据库压力过大。所以最终决定把图片上传到服务器,然后数据库中,并且把图片名称存储为用户id+上传时间戳,保证用户头像不重复,数据库中存储图片名称,在更新头像之前,根据数据库存储前一张图片名称,先删除上一张头像。展示时根据图片名称,在服务器中找到图片,并显示。
其中上传图片过程如下:
文件上传首先得引入两个jar包,建议在mvn库中下载,下载完粘贴到lib目录下。
然后是jsp中的from表单,需要设置一些参数。
- from表单中参数:
- action:提交路径
- method:post
- enctype:enctype属性规定在发送到服务器之前应该如何对表单数据进行编码。
- multipart/form-data:是指表单数据有多部分构成,既有文本数据,又有文件等二进制数据的意思。
- type="file":一定要设置Input的type属性设置成file,才能选择要上传的文件
- name:name 属性规定 input 元素的名称。name 属性用于对提交到服务器后的表单数据进行标识,或者在客户端通过 JavaScript 引用表单数据。
注释:只有设置了 name 属性的表单元素才能在提交表单时传递它们的值。
- 后台
// 上传配置
private static final int MEMORY_THRESHOLD = 1024 * 1024 * 3; // 3MB
private static final int MAX_FILE_SIZE = 1024 * 1024 * 40; // 40MB
private static final int MAX_REQUEST_SIZE = 1024 * 1024 * 50; // 50MB
String uploadPath = this.getClass().getClassLoader().getResource("/").getPath();
public User updataImg(HttpServletRequest request, HttpServletResponse response, User user) throws IOException {
uploadPath = uploadPath.split("WEB-INF")[0] + "uploads";
// uploadPath = uploadPath.split("out")[0] + "web/uploads";
// 配置上传参数
DiskFileItemFactory factory = new DiskFileItemFactory();
// 设置内存临界值 - 超过后将产生临时文件并存储于临时目录中
factory.setSizeThreshold(MEMORY_THRESHOLD);
// 设置临时存储目录
factory.setRepository(new File(System.getProperty("java.io.tmpdir")));
ServletFileUpload upload = new ServletFileUpload(factory);
// 设置最大文件上传值
upload.setFileSizeMax(MAX_FILE_SIZE);
// 设置最大请求值 (包含文件和表单数据)
upload.setSizeMax(MAX_REQUEST_SIZE);
// 中文处理
upload.setHeaderEncoding("UTF-8");
// 如果目录不存在则创建
File uploadDir = new File(uploadPath);
if (!uploadDir.exists() && !uploadDir.isDirectory()) {
uploadDir.mkdir();
}
try {
// 解析请求的内容提取文件数据
List<FileItem> formItems = upload.parseRequest(request);
if (formItems != null && formItems.size() > 0) {
// 迭代表单数据
for (int i = 0; i < formItems.size(); i++) {
// 处理不在表单中的字段,且选中想要修改的头像情况
if (!formItems.get(i).isFormField() && formItems.get(i).getName() != "" && formItems.get(i).getName() != null) {
delectImg(user);
//获得当前时间戳,头像上传文件名使用电话号码和当前时间戳表示
long day = new Date().getTime();
String fileName = user.getUid() + day + "." + new File(formItems.get(i).getName()).getName().split("\\.")[1];
//设置文件路径
String filePath = uploadPath + "/" + fileName;
File storeFile = new File(filePath);
// 在控制台输出文件的上传路径
// 保存文件到硬盘
formItems.get(i).write(storeFile);
user.setUimg(fileName);
} else {//普通文本的字段
}
}
}
} catch (Exception ex) {
request.setAttribute("message",
"错误信息: " + ex.getMessage());
}
return user;
}
//删除前头像
public void delectImg(User user) {
if (user.getUimg() != null) {
uploadPath = uploadPath.split("WEB-INF")[0] + "uploads";
File fileImg = new File(uploadPath + "/" + user.getUimg());
if (fileImg.exists()) {
fileImg.delete();
}
}
}
后台封装上传图片到工具类中,即完成图片上传到tomcat项目的指定路径
问题:
在上传时,可以上传到本地项目中,也可以上传到编译以后的文件夹中。区别是上传到本地文件夹中,编译以后的的文件夹不及时更新,前台是从编译以后的文件夹查找资源,所以会出现不及时显示的问题。this.getClass().getClassLoader().getResource("/").getPath();可以获得当前项目编译后的路径,通过拼接查找到编译后的文件夹中的上传文件夹,前台能够直接显示。