提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


文章目录

  • 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>
  • 或者手动加入(这两个包已经上传到本博客的资源下载文件里面):

.net java 传文件下载 java文件上传下载项目_maven


如果后面的代码不能够运行:
请手动把这两个包加入到tomcat中的lib文件夹下面

.net java 传文件下载 java文件上传下载项目_maven_02

重点:
这里可能会经常遇到,都可以采用这种方式。因为有时候使用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文件夹里面。

.net java 传文件下载 java文件上传下载项目_.net java 传文件下载_03

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();
        }
    }
}
  1. 保存的的路径是服务器的tomcat路径.
String uploadPath = this.getServletContext().getRealPath("/WEB-INF/classes/");
  1. 这里面也有个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.运行截图

.net java 传文件下载 java文件上传下载项目_html_04


.net java 传文件下载 java文件上传下载项目_html_05

二、文件下载(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.运行截图

.net java 传文件下载 java文件上传下载项目_.net java 传文件下载_06


点击“下载模板”

.net java 传文件下载 java文件上传下载项目_maven_07

总结

point:

  • 文件上传、下载用到的了管道流方式,也可用之前的流方式(但是可能会出现中文乱码);
  • 文件上传操作,最好把文件上传的路径设为服务器上(例如这里是tomcat),而不是本地绝对路径,或者本项目路径。
  • 这里可能会遇到tomcat少包,原因就是:没有把第三方包加入到tomcat的bin目录中。