提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- javaweb实现文件上传和下载
- 一、文件上传(excel表格为例)
- 1.代码示例
- 2.运行截图
- 二、文件下载(excel表格为例)
- 1.代码示例
- 2.运行截图
- 总结
javaweb实现文件上传和下载
重点重点重点阿:
- IDE为
idea
,使用的服务器是tomcat
。 - 还需要导入两个包通过(
pom.xml
):
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
- 或者手动加入(这两个包已经上传到本博客的资源下载文件里面):
如果后面的代码不能够运行:
请手动把这两个包加入到tomcat
中的lib
文件夹下面
重点:
这里可能会经常遇到,都可以采用这种方式。因为有时候使用pom.xml自动下载第三方包,但是包可能只在本项目中,不在tomcat服务器上,需要同步到服务器上或者手动把第三方包复制进去。
一、文件上传(excel表格为例)
1.代码示例
web前端代码如下(示例)
registerList.jsp:
<form action="../upload.do" enctype="multipart/form-data" method="post">
<p>上传用户:<input type="text" name="username"></p>
<p><input type="file" name="file"></p>
<p>
<input type="submit"> | <input type="reset"> </p>
</form>
通过action=“…/upload.do”会自动调转到servlet中,这里为什么要用"…"返回上一层路径是因为我的registerList.jsp在register文件夹里面。
servlet中的代码如下:
这里面代码很多,有用的文件上传代码其实不多,通过管道流的方式进行上传,其余代码大多就是为了判断文件格式,解决中文乱码,以及对文件进行加密等安全操作。
FileServlet.java
package edu.login.servlet.user;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.UUID;
public class FileServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 判断表单是否包含文件上传控件
if (!ServletFileUpload.isMultipartContent(req)) { // 不包含文件上传控件,即普通表单
return;
}
// 创建上传文件的保存路径:外界无法直接访问
String uploadPath = this.getServletContext().getRealPath("/WEB-INF/classes/");//这里也可以设置为绝对路径
File uploadFile = new File(uploadPath);
makeDirIfNotExist(uploadFile);
// 创建临时文件的保存路径
String tmpPath = this.getServletContext().getRealPath("/WEB-INF/tmp");
File tmpFile = new File(tmpPath);
makeDirIfNotExist(tmpFile);
// 1、创建DiskFileItemFactory对象
DiskFileItemFactory factory = getDiskFileItemFactory(tmpFile);
// 2、创建ServletFileUpload对象
ServletFileUpload servletFileUpload = getServletFileUpload(factory);
// 3、解析请求并处理文件传输
String msg = "";
try {
msg = uploadParseRequest(req, servletFileUpload, uploadPath);
} catch (FileUploadException e) {
e.printStackTrace();
}
req.setAttribute("msg", msg);
req.getRequestDispatcher("/print.jsp").forward(req, resp);
}
private String uploadParseRequest(HttpServletRequest httpServletRequest, ServletFileUpload servletFileUpload, String uploadPath)
throws FileUploadException, IOException {
String msg = "";
// 解析前端请求,将每个表单项解析并封装成FileItem对象
List<FileItem> fileItems = servletFileUpload.parseRequest(httpServletRequest);
for (FileItem fileItem : fileItems) {
// 判断表单项是否为上传文件
if (fileItem.isFormField()) { // 普通文本
String filedName = fileItem.getFieldName(); // 获取字段名:表单项name属性的值
String value = fileItem.getString("UTF-8"); // FileItem对象中保存的数据流内容:即表单项为普通文本的输入值
System.out.println(filedName + ":" + value);
} else { // 上传文件
// ------------------------1、处理文件------------------------
String uploadFileName = fileItem.getName();// 上传文件名
System.out.println("上传的文件名:" + uploadFileName);
if (uploadFileName == null || uploadFileName.trim().equals("")) { // 文件名为空值或空
continue; // 进入下一轮循环,判断下一个FileItem对象
}
String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1); // 文件后缀名
System.out.println("文件信息【文件名:" + uploadFileName + ",文件类型:" + fileExtName + "】");
// 使用UUID保证文件名唯一
String uuidPath = UUID.randomUUID().toString();
// ------------------------2、处理路径------------------------
// 存储路径:uploadPath
String realPath = uploadPath; // 真实存在的路径
// 给每个文件创建一个文件夹
File realPathFile = new File(realPath);
makeDirIfNotExist(realPathFile);
// ------------------------3、文件传输------------------------
// 获得输入流
InputStream is = fileItem.getInputStream();
// 获得输出流
FileOutputStream fos = new FileOutputStream(realPathFile + "/" + uploadFileName);
// 创建缓冲区
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
msg = "文件上传成功!";
fileItem.delete(); // 上传成功,清除临时文件
fos.close();
is.close();
}
}
return msg;
}
private ServletFileUpload getServletFileUpload(DiskFileItemFactory factory) {
// ServletFileUpload servletFileUpload = new ServletFileUpload(factory); // 构造方法设置FileItemFactory
ServletFileUpload servletFileUpload = new ServletFileUpload();
servletFileUpload.setFileItemFactory(factory); // 设置FileItemFactory
// ------------------------辅助功能------------------------
// 监听文件上传进度
servletFileUpload.setProgressListener(new ProgressListener() {
/**
*
* @param pBytesRead 已读取的文件大小
* @param pContentLength 文件大小
* @param pItems
*/
@Override
public void update(long pBytesRead, long pContentLength, int pItems) {
String percentage = (int) (((double) pBytesRead / pContentLength) * 100) + "%";
System.out.println("总大小:" + pContentLength + ",已上传:" + pBytesRead + "\t" + percentage);
}
});
// 处理乱码问题
servletFileUpload.setHeaderEncoding("UTF-8");
// 设置单个上传文件的最大值
servletFileUpload.setFileSizeMax(1024 * 1024 * 10); // 10M
// 设置总共上传文件的最大值
servletFileUpload.setSizeMax(1024 * 1024 * 10); // 10M
return servletFileUpload;
}
/**
* 获得磁盘文件项目工程,设置缓冲文件夹及缓冲区大小
*
* @param tmpFile 缓冲文件夹
* @return
*/
private DiskFileItemFactory getDiskFileItemFactory(File tmpFile) {
// return new DiskFileItemFactory(1024 * 1024, tmpFile);
DiskFileItemFactory factory = new DiskFileItemFactory();
// ------------------------辅助功能------------------------
factory.setSizeThreshold(1024 * 1024); // 1M(缓冲区大小):上传文件大于缓冲区大小时,fileupload组件将使用临时文件缓存上传文件
factory.setRepository(tmpFile); // 临时文件夹
return factory;
}
/**
* 如果文件目录不存在,为其创建目录
*
* @param file
*/
private void makeDirIfNotExist(File file) {
if (!file.exists()) {
file.mkdir();
}
}
}
- 保存的的路径是服务器的tomcat路径.
String uploadPath = this.getServletContext().getRealPath("/WEB-INF/classes/");
- 这里面也有个
uuid
:其实就是为上传的文件创建一个零临时文件(随机文件名),保护文件。
web.xml配置
<servlet>
<servlet-name>FileServlet</servlet-name>
<servlet-class>edu.login.servlet.user.FileServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FileServlet</servlet-name>
<url-pattern>/upload.do</url-pattern>
</servlet-mapping>
2.运行截图
二、文件下载(excel表格为例)
1.代码示例
web前端代码如下(示例)
registerList.jsp:
<h2> <a href="../download.do" > 下载模板 </a></h2>
这里的action="…/download.do"这里点击后会调转到所配置的servlet中,为什么要用“…”是因为我的registerList.jsp在文件夹register中,而不是直接在web目录下面。
servlet中的代码如下:
FileDownServlet.java
package edu.login.servlet.file;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
public class FileDownServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1.获取下载文件的路径**
String realPath="E:\\maven\\servlet-02\\target\\classes\\data.xlsx";//这里用的是文件的绝对路径,也可以设置为相对路径
System.out.println("下载文件路径"+realPath);
// 2.下载的文件名
String fileName="data.xlsx";
// 3.设置让浏览器支持所下载的文件(设置中文编码utf-8格式)
resp.setHeader("Content-Disposition", "attachment;filename="+ URLEncoder.encode(fileName, "utf-8"));
// 4.获取下载文件的输入流
FileInputStream in= new FileInputStream(realPath);
// 5.创建缓冲区
int len=0;
byte[] buffer=new byte[1024*3];
// 6.获取OutputStream对象
ServletOutputStream out=resp.getOutputStream();
// 7.将FileOutputStream流写入到buffer缓冲区
// 8.使用OutputStream将缓冲区中的数据输入到客户端
while((len=in.read(buffer))>0){
out.write(buffer,0,len);
}
in.close();
out.close();
req.getRequestDispatcher("/register/registerList.jsp").forward(req, resp);
}
}
配置web.xml文件
<servlet>
<servlet-name>FileDownServlet</servlet-name>
<servlet-class>edu.login.servlet.file.FileDownServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FileDownServlet</servlet-name>
<url-pattern>/download.do</url-pattern>
</servlet-mapping>
2.运行截图
点击“下载模板”
总结
point:
- 文件上传、下载用到的了
管道流方式
,也可用之前的流方式
(但是可能会出现中文乱码); - 文件上传操作,最好把文件上传的路径设为服务器上(例如这里是tomcat),而不是本地绝对路径,或者本项目路径。
- 这里可能会遇到tomcat少包,原因就是:没有把第三方包加入到tomcat的bin目录中。