记录一次图片上传
一、提前准备
1、需要知道
一般进行图片上传处理的时候,将图片保存到oss中,路径保存到数据库,使用的时候调用路径即可
前端代码: 在java中使用form表单上传文件时form标签中必须加上 enctype=“multipart/form-data”
enctype: 规定在发送到服务器之前应该如何对表单数据进行编码。
enctype的三个参数:
|- application/x-www-form-urlencoded: 在发送前编码所有字符(默认)
|- multipart/form-data:
不对字符编码。在使用包含文件上传控件的表单时,必须使用该值。指定传输数据为二进制类型,比如图片、音频、文件等
|- text/plain: 空格转为"+"加号,但不对特殊字符编码
总结:
|- 表单提交方式:
post,因为get方式传参,最大传输量为 4K
|- form表单有一个属性为 enctype
form表单有一个属性为 MIME 默认值为 application/x-www-form-urlencoded 不支持文件上传
多媒体(文件)表单值需要修改改属性为:
enctype="multipart/form-data"
|- 文件上传的表单元素
type = file
2、依赖
<!-- 文件上传依赖 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.4</version>
</dependency>
二、编码
/webapp/student/updateStudent.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>更新</title>
</head>
<body>
<%-- 记得添加enctype="multipart/form-data --%>
<form action="${pageContext.request.contextPath}/upload" method="post" align="center" enctype="multipart/form-data">
用户id:<input type="text" name="id" value="${requestScope.student.studentId}" readonly><br>
用户名:<input type="text" name="name"
value="${requestScope.student.studentName}" readonly><br>
手机号:<input type="text" name="mobile" value="${requestScope.student.mobile}"><br>
上传头像:<input type="file" name="picture"><br>
<input type="submit" value="修改"><br>
</form>
</body>
</html>
/java/com/qhx/servlet/Upload.java
package com.qhx.factory;
import com.qhx.entity.RecommendStudent;
import com.qhx.service.RecommendStudentService;
import com.qhx.service.impl.RecommendStudentServiceImpl;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.util.List;
@WebServlet("/upload")
public class UploadServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1、设置post方式请求的编解码格式
req.setCharacterEncoding("utf-8");
// 设置请求接收的参数,便于封装对象
String name = null;
String mobile = null;
int id = 0;
String imagePath = null;
RecommendStudent student = null;
// 2、接收请求参数
// 2.1、接收文件信息
// 设置客户端提交文件,服务端保存的文件夹位置与保存文件名
/*ServletContext context = req.getServletContext(); // 获取整个项目对象
String path = context.getRealPath("/file"); // 获取指定文件夹的绝对路径*/
//String path = "D:\\Java\\Mybatis02_baizhi\\src\\main\\webapp\\image";
// 图片上传后并未直接打包到tomcat的输出目录里,故需要重启服务器才能访问已上传的图片。这里将图片保存路径改为tomcat的输出目录(target/..),就不需要重启服务器访问了
String path = "D:\\Java\\Mybatis02_baizhi\\target\\Mybatis02_baizhi-1.0-SNAPSHOT\\image";
// 文件上传的接收配置
int MEMORY_THRESHOLD = 1024*1024*5; //内存临界值5MB,超出临界值后生成临时文件并保存到临时目录
int MAX_FILE_SIZE = 1024*1024*40; //文件上传最大容量
int MAX_REQUEST_SIZE = 1024*1024*50; // form表单提交数据最大容量
// 3、上传数据并保存
// 3.1、检测请求体重是否包含多媒体信息(文件/视频/音频)
boolean flag = ServletFileUpload.isMultipartContent(req);
// 如果包含
if (flag){
// 基于磁盘文件创建工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
// 3.2 配置上传参数
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"); // 上传文件中文编码集
// 3.3 设置文件保存的目录 target文件夹下
File file = new File(path);
if (!file.exists()){
// 若文件夹不存在,则新建 mkdir可以创建单层目录,mkdirs可以创建多层目录
file.mkdirs();
}
// 3.4 解析请求内容提取文件数据
try {
// 将请求体中的信息映射为 FileItem对象 (普通表单信息+多媒体文件信息)
List<FileItem> items = upload.parseRequest(req);
// 若请求体中存在表单信息
if (items!=null && items.size()>0){
// 迭代获取表单数据
for (FileItem item:items){
// 如果是普通表单元素
if (item.isFormField()){
if (item.getFieldName().equals("name")){
name = item.getString("UTF-8");
System.out.println("username="+name);
}else if (item.getFieldName().equals("mobile")){
mobile = item.getString("UTF-8");
System.out.println("mobile="+mobile);
}else if (item.getFieldName().equals("id")){
String sid = item.getString("UTF-8");
id = Integer.parseInt(sid);
System.out.println("id="+id);
}
}else { // 如果是多媒体表单元素
// 判定指定类型文件
if (item.getFieldName().equals("picture")){
// 获取上传的文件
File srcUploadFilName = new File(item.getName());
// 获取上传的文件名
String uploadFileName = srcUploadFilName.getName();
// 获取文件后缀
String[] split = uploadFileName.split("\\.");
String lastName = "";
if (split.length>1){
lastName = split[split.length-1];
}
System.out.println(lastName);
// 路径,使用时间戳处理 因为jsp有时无法解析中文路径,故命名图片时直接给图片重命名(不含中文)
String uploadFilePath = path + File.separator + System.currentTimeMillis() +"image."+ lastName;
// 保存的新文件
File descUploadFile = new File(uploadFilePath);
// 查看保存文件的绝对路径
System.out.println(uploadFilePath);
// 绝对路径转换为可以在img>src标签中用的格式(/项目名/image/...)
// 去掉,留下image\\xxx.jpg
imagePath = uploadFilePath.replace("D:\\Java\\Mybatis02_baizhi\\target\\Mybatis02_baizhi-1.0-SNAPSHOT\\","");
// "\\" 替换为 "/"
imagePath = imagePath.replace("\\","/");
System.out.println(imagePath);
// 保存新文件到磁盘
item.write(descUploadFile);
System.out.println("上传成功!");
}
}
}
}
// 封装对象,执行service的更新方法
RecommendStudentService studentService = new RecommendStudentServiceImpl();
student = studentService.selectById(id);
student.setMobile(mobile);
student.setImage(imagePath);
studentService.updateCon(student);
// 重新查询修改后的对象,存入作用域,供后续页面使用
RecommendStudent student1 = studentService.selectById(id);
System.out.println(student1);
// 不用req作用域,因为下方没有请求转发
HttpSession session = req.getSession();
session.setAttribute("student",student1);
}catch (Exception e){
e.printStackTrace();
}
}else {
PrintWriter out = resp.getWriter();
out.print("enctype属性写错");
out.flush();
return;
}
// 获取项目路径
String contextPath = req.getContextPath();
// 跳转到图片展示页面
resp.sendRedirect(contextPath+"/student/showPicture.jsp");
}
}
/webapp/student/showPicture.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
<html>
<head>
<title>展示图片</title>
<meta charset="UTF-8">
</head>
<body>
<h1>欢迎您:${sessionScope.student.studentName}</h1>
<img src="${pageContext.request.contextPath}/${sessionScope.student.image}" height="300" width="400">
</body>
</html>