javaWeb 文件上传及下载

javaWeb文件上传及下载

前言

网络上最常用的就是文件的上传和下载,本文讲解基于org.apache.commons.fileupload包及org.apache.commons.io包实现文件上传;通过设置响应头属性并基于文件流方式实现文件下载。

一、文件上传

1、实现思路

  1. 文件上传是通过表单上传,因此首先需要判断表单中是否包含文件类型的标签,如果表单中没有文件类型的标签,表明该表单中不包含文件上传的功能,无需后续操作;否则,表明该表单中包含文件上传的功能,继续进行文件上传的后续操作。
//该方法判断表单中是否包含上传文件,返回true代表包含,否则代表不包含
ServletFileUpload.isMultipartContent(HttpServletRequest request)
  1. 在服务器中创建保存文件的文件夹,为了保证上传文件的安全性,建议将文件夹建在项目的WEB-INF目录,因为该目录下的文件,无法直接被用户访问,一定程度上保证了安全性。
  2. 创建ServletFileUpload对象,基于该对象实现用户上传文件。
//基于该构造方法,创建ServletFileUpload对象。
//FileItemFactory 是一个接口,DiskFileItemFactory类实现了该接口,
//该类用于对文件夹进行管理,如设置文件夹存储空间大小的阈值,默认阈值是1M。
public ServletFileUpload(FileItemFactory fileItemFactory);
  1. 基于ServletFileUpload对象获取表单中的每一个标签控件,通过判断标签的类型依次对该标签内容进行处理,如果是文件类型标签,则通过文件流的方式将文件上传到服务器。为了避免文件因重名而导致覆盖丢失,本文使用UUID类生成唯一的字符串,以该字符串命名文件夹,将上传的文件保存在该文件夹下。

2、实现代码

2.1 pom 依赖文件
 <dependencies>

    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>4.0.1</version>
    </dependency>

    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>jsp-api</artifactId>
      <version>2.1</version>
    </dependency>

    <dependency>
      <groupId>javax.servlet.jsp.jstl</groupId>
      <artifactId>jstl-api</artifactId>
      <version>1.2</version>
    </dependency>

    <dependency>
      <groupId>taglibs</groupId>
      <artifactId>standard</artifactId>
      <version>1.1.2</version>
    </dependency>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
    </dependency>

    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.2.1</version>
    </dependency>

    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-io</artifactId>
      <version>1.3.2</version>
    </dependency>
  </dependencies>
2.2 前端jsp代码
<html>
<body>
<h2>上传文件</h2>

<form action="${pageContext.request.contextPath}/upload.do" method="post" enctype="multipart/form-data">
    <p>上传用户:<input type="text" name="username"></p>
    <p>上传文件1:<input type="file" name="file1"></p>
    <p>上传文件2:<input type="file" name="file2"></p>
    <p>
        <input type="submit" value="提交"> | <input type="reset" value="重置">
    </p>
</form>
</body>
</html>

在这里插入图片描述

2.3 web.xml文件配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0"
         metadata-complete="true">
  <servlet>
    <servlet-name>FileServlet</servlet-name>
    <servlet-class>com.sun.servlet.FileServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>FileServlet</servlet-name>
    <url-pattern>/upload.do</url-pattern>
  </servlet-mapping>

</web-app>
2.4 后台代码
public class FileServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1. 判断表单是否带上传文件
        if(!ServletFileUpload.isMultipartContent(req))
        {
            return;
        }
        //2. 创建上传文件保存在服务器中的目录,建议在WEB-INF路径下,可以一定程度上保证安全
        String uploadPath = this.getServletContext().getRealPath("/WEB-INF/upload");
        System.out.println("上传文件根目录:"+uploadPath);
        File uploadFile = new File(uploadPath);
        if (!uploadFile.exists())
        {
            uploadFile.mkdir();
        }
        //3. 创建磁盘文件库
        DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
        //4. 获取servlet文件上传对象
        ServletFileUpload fileUpload = new ServletFileUpload(diskFileItemFactory);
        //4.1 监控上传进度
        fileUpload.setProgressListener(new ProgressListener() {
            public void update(long l, long l1, int i) {
                System.out.println("文件总大小:"+l1+" 已上传:"+l);
            }
        });
        //4.2 处理乱码问题
        fileUpload.setHeaderEncoding("UTF-8");
        //4.3 设置单个文件大小的最大值
        fileUpload.setFileSizeMax(1024*1024*10);
        //4.4 设置总共能上传的文件大小最大值
        fileUpload.setSizeMax(1024*1024*10);
        //5. 处理上传的文件
        try {
            //5.1 获取表单中的每一个控件
            List<FileItem> fileItems = fileUpload.parseRequest(req);
            for (FileItem fileItem : fileItems) {
                if (fileItem.isFormField()) {//当前控件为普通表单
                    String fieldName = fileItem.getFieldName();
                    String value = fileItem.getString("UTF-8");
                    System.out.println(fieldName + ":" + value);
                } else//当前控件为带文件的表单
                {
                    //5.2 获取文件路径
                    String uploadFileName = fileItem.getName();
                    //5.3 对获取的文件字符串路径进行处理
                    if (uploadFileName.trim().equals("") || uploadFileName == null)
                        continue;
                    //5.3.1  获取文件名
                    String fileName = uploadFileName.substring(0,uploadFileName.lastIndexOf("."));
                    System.out.println("文件信息:"+"[文件名:"+fileName]");
                    //5.4 生成唯一的字符串,标识文件名,保证文件不会因为重名和覆盖
                    UUID uuidName = UUID.randomUUID();
                    //5.5 为上传的文件创建一个唯一命名的文件夹
                    String realUploadPath = uploadPath + "//" + uuidName;
                    File realUploadFile = new File(realUploadPath);
                    if (!realUploadFile.exists())
                        realUploadFile.mkdir();
                    //5.6 将上传的文件保存到上面存储的唯一文件夹中
                    //5.6.1  获取上传文件的流
                    InputStream inputStream = fileItem.getInputStream();
                    //5.6.2 将文件流写出到指定服务器文件
                    FileOutputStream fos = new FileOutputStream(realUploadPath + "//" + uploadFileName);
                    byte[] buffer = new byte[1024 * 1024];
                    int len = 0;
                    while ((len = inputStream.read(buffer)) > 0) {
                        fos.write(buffer, 0, len);
                    }
                    fos.close();
                    inputStream.close();
                    fileItem.delete();//上传成功,清除临时文件
                }
            }
        } catch (FileUploadException e) {
            e.printStackTrace();
        }
        String msg="文件上传成功";
        //请求转发
        req.setAttribute("msg",msg);
        req.getRequestDispatcher("info.jsp").forward(req,resp);
    }
}

二、下载指定文件

通过设置响应头属性,实现文件下载。

resp.setHeader("content-disposition","attachment;filename="+ URLEncoder.encode(fileName));

后台代码。

public class FileServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1. 获取下载文件路径
        ServletContext context = this.getServletContext();
        String realPath = this.getServletContext().getRealPath("/WEB-INF/classes/1.jpeg");
        //2. 获取下载文件名
        String fileName = realPath.substring(realPath.lastIndexOf("\\")+1);
        //3. 浏览器设置下载文件方法, URLEncoder.encode解决中文乱码
        resp.setHeader("content-disposition","attachment;filename="+ URLEncoder.encode(fileName));
        //4. 获取下载文件的输入流
        FileInputStream in = new FileInputStream(realPath);
        //5. 创建缓冲区
        int len=0;
        byte[] buffer =new byte[1024];
        //6. 获取输出对象
        ServletOutputStream out = resp.getOutputStream();
        //7. 将缓冲区中的数据输出
        while ((len=in.read(buffer))>0)
            out.write(buffer,0,len);
        in.close();
        out.close();
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
  • 8
    点赞
  • 93
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mekeater

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值