JAVAweb-文件上传
1、创建一个新的项目,导入依赖
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<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>2.6</version>
</dependency>
2、编写jsp页面
- 文件上传页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<%--
GET:上传文件大小有限制
POST:上传文件大小没有限制
${pageContext.request.contextPath}
--%>
<form action="upload.do" enctype="multipart/form-data" method="post">
上传用户:<input type="text" name="username"><br/>
<P><input type="file" name="file1"></P>
<P><input type="file" name="file1"></P>
<P><input type="submit" value="提交"> | <input type="reset"></P>
</form>
</body>
</html>
- 上传成功页面
<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>Insert title here</title>
</head>
<body>
<%=request.getAttribute("msg")%>
</body>
</html>
3、Servelet类
@WebServlet("/upload.do")
public class FileServlet extends HttpServlet {
protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
//判断上传的文件是普通表单还是带文件的表单
if (!ServletFileUpload.isMultipartContent(request)) {
return;//终止方法运行,说明这是一个普通表单,直接返回
}
//创建上传文件的保存路径,建议在WEB-INF路径下,安全,用户无法直接访问上传的文件
String uploadPath = this.getServletContext().getRealPath("/WEB-INF/upload");
File uploadFile = new File(uploadPath);
if (!uploadFile.exists()&& !uploadFile.isDirectory()) {
System.out.println(uploadFile+"不存在,需要创建!");
uploadFile.mkdir();//如果没有这个目录就创建
}
//缓存,临时文件
//临时路径,假如文件超过了预期的大小,我们就把他放到一个临时文件中,过几天自动删除,或者提醒用户转为永久保存
String tempPath = this.getServletContext().getRealPath("/WEB-INF/temp");
File tempFile = new File(tempPath);
if (!tempFile.exists()) {
tempFile.mkdir();
}
/*
ServletFileUpload 负责处理上传的文件数据,并将表单中每个输出封装成一个FileItem对象
在使用ServletFileUpload对象解析请求时需要DiskFileItemFactory对象
所以我们需要在进行解析工作前构造好DiskFileItemFactory对象
通过ServletFileUpload对象的构造方法或setFileItemFactory()方法设置ServletFileUpload对象的fileItemFactory属性
*/
try {
//1、创建DiskFileItemFactory对象,处理文件上传路径或者大小限制的;
DiskFileItemFactory factory = getDiskFileItemFactory(tempFile);
//2、获取ServletFileUpload
ServletFileUpload upload = getServletFileUpload(factory);
//3、处理上传文件
//把前端请求解析,封装成一个FileItem对象,需要从ServletFileUpload对象中获取
String msg = uploadParseRequest(upload, request, uploadPath);
// Servlet请求转发消息
System.out.println(msg);
if (msg == "文件上传成功!") {
// Servlet请求转发消息
System.out.println("文件位置在:"+uploadPath);
request.setAttribute("msg", msg);
request.getRequestDispatcher("info.jsp").forward(request, response);
} else {
msg = "请上传文件";
request.setAttribute("msg", msg);
request.getRequestDispatcher("info.jsp").forward(request, response);
}
} catch (FileUploadException e) {
e.printStackTrace();
}
}
//创建DiskFileItemFactory对象,处理文件上传路径或者大小限制的;
public static DiskFileItemFactory getDiskFileItemFactory(File file) {
DiskFileItemFactory factory = new DiskFileItemFactory();
//通过工厂设置一个缓冲区,当上传的文件大于这个缓冲区的时候,将他放到临时文件
factory.setSizeThreshold(1024 * 1024);//缓冲区大小为1m
factory.setRepository(file);
return factory;
}
//获取ServletFileUpload
public ServletFileUpload getServletFileUpload(DiskFileItemFactory factory) {
//创建一个文件上传解析器
ServletFileUpload upload = new ServletFileUpload(factory);
//监听上传进度
upload.setProgressListener(new ProgressListener() {
//pBytesRead:已读取到的文件大小
//pContentLength:文件大小
@Override
public void update(long pBytesRead, long pContentLength, int pItems) {
System.out.println("总大小:" + pContentLength + ",已上传:" + pBytesRead);
}
});
//处理乱码问题
upload.setHeaderEncoding("UTF-8");
//设置单个·文件的最大值
upload.setFileSizeMax(1024 * 1024 * 10);
return upload;
}
//把前端请求解析,封装成一个FileItem对象,需要从ServletFileUpload对象中获取
public static String uploadParseRequest(ServletFileUpload upload, HttpServletRequest request, String uploadPath)
throws FileUploadException, IOException {
String msg = "";
List<FileItem> fileItems = upload.parseRequest(request);
//fileItem 每一个表单对象
for (FileItem fileItem : fileItems
) {
//判断上传的文件是普通的表单还是带文件的表单
if (fileItem.isFormField()) {
//getFieldName()指的是前端表单控件的name
String name = fileItem.getFieldName();
String value = fileItem.getString("UTF-8");
System.out.println(name + ":" + value);
} else {//文件
//处理文件
String uploadFileName = fileItem.getName();
System.out.println("上传的文件名: " + uploadFileName);
//可能存在文件名不合法的情况
if (uploadFileName.trim().equals("") || uploadFileName == null) {
continue;
}
//获得上传的文件名
String fileName = uploadFileName.substring(uploadFileName.lastIndexOf("/") + 1);
//获得文件的后缀名
String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1);
/*
如果文件后缀 fileExtName 不是我们所需要的,
就直接return,不处理,告诉用户文件类型不对
*/
System.out.println("文件信息[文件名: " + fileName + " ---文件类型" + fileExtName + "]");
//UUID(唯一识别的通用码,保证文件名唯一)
//UUID.randomUUID(),随机生成一个唯一识别的通用码
String uuidPath = UUID.randomUUID().toString();
//存放地址
//存到哪?uploadPath
//文件真实存在的路径 realPath
String realPath = uploadPath + "/" + uuidPath;
//给每个文件创建一个对应的文件夹
File realPathFile = new File(realPath);
if (!realPathFile.exists()) {
realPathFile.mkdir();
}
//文件传输
//获得文件上传的流
InputStream in = fileItem.getInputStream();
//创建一个文件输出流
FileOutputStream fos = new FileOutputStream(realPath + "/" + fileName);
//创建一个缓冲区
byte[] buffer = new byte[1024 * 1024];
//判断是否读取完毕
int len = 0;
//如果大于0说明还存在数据,继续读取
while ((len = in.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
//关闭流
fos.close();
in.close();
msg = "文件上传成功!";
fileItem.delete();//上传成功,删除临时文件
}
}
return msg;
}
}
4、文件上传成功后找不到文件位置解决
idea中javaweb项目文件上传成功,但是却在指定位置找不到文件???
出现这样的问题是tomcat部署的问题
- 以war部署,上传的文件会在Tomcat服务器文件夹下:
- 而以war exploded 部署,项目会在idea工作空间中部署,就可以找到上传的文件了