前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Servlet 3.0 文件上传与下载

Servlet 3.0 文件上传与下载

作者头像
wsuo
发布2020-07-30 23:15:38
1K0
发布2020-07-30 23:15:38
举报
文章被收录于专栏:技术进阶之路技术进阶之路

一、文件上传代码实现

代码实现很简单:

主要是用到了客户端 HTML 页面的表单元素,使用<form> 标签的 enctype 属性,并设置它的值为 multipart/formdata,意思是:多部分/表单数据,同时使用<input type="file"> 的输入域用于指定上传的文件。

关于form表单 enctype属性:

描述

application/x-www-form-urlencoded

在发送前编码所有字符(默认)

multipart/form-data

不对字符编码,每一个表单项分割为一个部件

text/plain

空格转换为加号,但不对特殊字符编码

这是前端代码:

代码语言:javascript
复制
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>文件上传</title>
  </head>
  <body>
  ${message}<br>
  <form action="fileUpload" method="post" enctype="multipart/form-data">
    <table>
      <tr>
        <td align="center" colspan="2">文件上传</td>
      </tr>
      <tr>
        <td>用户名: </td>
        <td><input type="text" name="username" size="30"></td>
      </tr>
      <tr>
        <td>文件: </td>
        <td><input type="file" name="filename" size="30"></td>
      </tr>
      <tr>
        <td><input type="submit" value="提交"></td>
        <td><input type="reset" value="重置"></td>
      </tr>
    </table>
  </form>
  </body>
</html>

这是后台的接口:

代码语言:javascript
复制
@WebServlet(name = "FileUploadServlet", urlPatterns = "/fileUpload")
@MultipartConfig(location = "D:\\", fileSizeThreshold = 1024)
public class FileUploadServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String path = this.getServletContext().getRealPath("/");//返回web应用程序文档根目录
        String username = request.getParameter("username");
        Part part = request.getPart("filename");
        String message = "";

        if (part.getSize() > 1024 * 1024) {
            part.delete();
            message = "文件大小不能超过1MB";
        } else {
            path += "\\user\\" + username;
            File file = new File(path);
            if (!file.exists()) {
                file.mkdirs();
            }
            String h = part.getHeader("Content-Disposition");
            String fname = getFileName(h);
            part.write(path + "\\" + fname);
            message = "文件上传成功";
        }
        request.setAttribute("message", message);
        request.getRequestDispatcher("/index.jsp").forward(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }

    /**
     * 根据请求头解析出文件名
     * 请求头的格式:火狐和google浏览器下:form-data; name="file"; filename="snmp4j--api.zip"
     * IE浏览器下:form-data; name="file"; filename="D:\snmp4j--api.zip"
     * @param header 请求头
     * @return 文件名
     */
    public String getFileName(String header) {
        /**
         * String[] tempArr1 = header.split(";");
         * 代码执行完之后,在不同的浏览器下,tempArr1数组里面的内容稍有区别:
         * 火狐或者google浏览器下:tempArr1={form-data,name="file",filename="snmp4j--api.zip"}
         * IE浏览器下:tempArr1={form-data,name="file",filename="D:\snmp4j--api.zip"}
         */
        String[] tempArr1 = header.split(";");
        /**
         *火狐或者google浏览器下:tempArr2={filename,"snmp4j--api.zip"}
         *IE浏览器下:tempArr2={filename,"D:\snmp4j--api.zip"}
         */
        String[] tempArr2 = tempArr1[2].split("=");
        //获取文件名,兼容各种浏览器的写法
        String fileName = tempArr2[1].substring(tempArr2[1].lastIndexOf("\\")+1).replaceAll("\"", "");
        return fileName;
    }
}

假如上传了一张图图片:

那么请求头信息为:


二、原理分析

当表单提交的时候,浏览器将表单的各部分发送到服务器端,在服务器端使用 partwrite()方法可以将文件保存在服务器的特定位置。

Part 接口为 Servlet3.0 新增的接口,在servlet.http 包下,它表示多部分表单的一个部分。

  • public String getHeader(String name):返回Part对象指定的MIME头的值。
  • public long getSize():返回Part 对象的大小。
  • public void write(String path):将Part对象写入到指定的位置。

必须使用@MultipartConfig注解:

  • 该注解告诉容器该 Servlet 能够处理 multipart/formdata的请求。
  • 使用该注解request对象才可以得到表单的各部分

常用的注解元素为:

也可以使用配置文件的方式进行配置,元素值与标签相同。

三、文件下载

代码语言:javascript
复制
/**
 * 文件下载 servlet
 */
@WebServlet(urlPatterns = "/downloadServlet")
public class DownloadServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1、文件存放路径
        String path = "D:/fileUpload/";
        // 2、需要下载的文件名
        String fileName = "test.jpg";
        File file = new File(path + fileName);
        response.reset();
        response.setCharacterEncoding("UTF-8");
        fileName = URLEncoder.encode(fileName, "UTF-8");
        response.setHeader("Content-Disposition", "attachment;fileName=" + fileName);
        InputStream input = new FileInputStream(file);
        ServletOutputStream out = response.getOutputStream();
        byte[] buff = new byte[1024];
        int len;
        while ((len = input.read(buff)) != -1) {
            out.write(buff, 0, len);
            out.flush();
        }
        input.close();
        out.close();
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

}

D:\fileUpload\test.jpg要有图片,才可以完成下载。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-03-06 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、文件上传代码实现
  • 二、原理分析
  • 三、文件下载
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档