栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

文件上传和下载

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

文件上传和下载

文章目录
  • 一、文件上传
    • 1.1 准备工作
      • 1.1.1 创建一个web项目
      • 1.1.2 准备jar包
      • 1.1.3 使用类介绍
      • 1.1.4 常用方法
    • 1.2 实现
      • 1.2.1 上传页面
      • 1.2.2 成功页面
      • 1.2.3 上传代码
      • 1.2.4 自定义方法
  • 二、文件下载
    • 2.1 步骤
    • 2.2 代码实现
  • 三、上传下载互动
    • 3.1 思路


学习视频来自于:秦疆(遇见狂神说)Bilibili地址
他的自学网站:kuangstudy

我们缺乏的不是知识,而是学而不厌的态度


一、文件上传 1.1 准备工作 1.1.1 创建一个web项目

使用开发工具创建一个maven管理的web项目

1.1.2 准备jar包

fileupload:jar包
commons-io:依赖jar包


    commons-fileupload
    commons-fileupload
    1.4


    commons-io
    commons-io
    2.11.0

1.1.3 使用类介绍

文件上传的注意事项

  1. 为保证服务器安全,上传的文件存放在一个外界无法直接访问的目录下面,比如WEB-INF目录下。
  2. 为了防止文件覆盖的现象发生,要为上传文件产生一个唯一的文件名:使用时间戳/UUID/MD5等手段实现。
  3. 要限制上传文件的最大值:因为服务器上硬盘资源很贵,不能让用户随意的使用。
  4. 限制文件上传类型:在收到上传文件名时,判断后缀名是否合法。

ServletFileUpload类
负责处理上传的文件数据,并将表单中的每个输入项都封装为一个FileItem对象,使用其parseRequest(HttpServletRequest) 方法可以将表单中每一个HTML标签提交的数据封装成一个FileItem对象,然后以List列表的形式返回,使用该方法处理上传文件简单易用。
但是ServletFileUpload对象解析请求时需要DIskFileItemFactory对象,我们在解析工作前构造好DIskFileItemFactory,通过ServletFileUpload构造器或setFileItemFactory()方法设置ServletFileUpload对象中fileItemFactory属性。

FileItem类
在HTML页面input标签必须有name
表单如果包含一个文件上传输入项的话,这个表单的enctype属性就必须设置为multipart/form-data

上传用户:
上传1:
上传2:

通过FileItem提交的数据封装成的对象,便于操作。

1.1.4 常用方法
// ServletFileUpload类
// 判断上传的文件是普通表单还是带文件表单
ServletFileUpload.isMultipartContent(req);
// FileItem类
//isFormField方法用于判断FileItem类对象封装的数据是一个普通文本表单
//还是一个文件表单,如果是普通表单字段则返回true,否则返回false
boolean isFormField();//即:只要是上传的文件,返回的就是false

//getFieldName方法用于返回表单标签name字段的值。
String getFieldName();//获取这个input的name属性值

//getString方法用于将FileItem对象中保存的数据流内容以一个字符串返回
String getString();//用字符串存储文件的数据流
    
//getName方法用于获得文件上传字段中的文件名
String getName();

//以流的形式返回上传文件的数据内容。
InputStream getInputStream()

//delete方法用来清空FileItem类对象中存放的主体内容
//如果主体内容被保存在临时文件中,delete方法将删除该临时文件。
void delete();
1.2 实现 1.2.1 上传页面

环境配置建后,先测试页面跳转后台没问题,在开始写上传。

上传用户:
上传1:
上传2:
1.2.2 成功页面
<%=request.getAttribute("msg")%>

上传成功

1.2.3 上传代码

上传不使用doGet,方法都放在doPost里面。

// 接收中文
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
// 判断上传的文件是普通表单还是带文件表单
if (ServletFileUpload.isMultipartContent(req)) {
    // 创建上传文件的保存路径,建议在WEB-INF路径下,安全,用户无法直接访问到
    String uploadPath = this.getServletContext().getRealPath("/WEB-INF/upload");
    File uploadFile = new File(uploadPath);
    if (!uploadFile.exists()) {
        uploadFile.mkdir();//没有这个目录就创建这个目录
    }
    String tmpPath = this.getServletContext().getRealPath("/WEB-INF/tmp");
    File tmpFile = new File(tmpPath);
    if (!tmpFile.exists()) {
        tmpFile.mkdir();//没有这个目录就创建这个目录
    }
    // 处理上传文件,需要通过流来获取,可以使用request.getInputstream();但是原生十分麻烦
    // 建议使用apache文件上传组件来实现,common-fileupload,它需要commons-is组件
    // 创建DiskFileItemFactory对象,处理文件路径或大小限制
    DiskFileItemFactory factory = this.getDiskFileItemFactory(tmpFile);
    ServletFileUpload upload = this.getServletFileUpload(factory);
    String msg = this.uploadParasRequest(upload, req, uploadPath);
    req.setAttribute("msg", msg);
    req.getRequestDispatcher("success.jsp").forward(req, resp);
} else {
    return;//终止方法,不是带文件的表单
}
1.2.4 自定义方法
// 获取磁盘对象
private DiskFileItemFactory getDiskFileItemFactory(File file) {
    
    // 1.创建DiskFileItemFactory对象,获取磁盘对象
    DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory(1024 * 1024, file);
    return diskFileItemFactory;
}
    
//2、创建ServletFileUpload对象,获取上传文件的解析对象
private ServletFileUpload getServletFileUpload(DiskFileItemFactory factory) {
    ServletFileUpload servletFileUpload = new ServletFileUpload(factory);
    // 监听文件上传速度
    servletFileUpload.setProgressListener(new ProgressListener() {
        //
        @Override
        public void update(long pBytesRead, long pContentLength, int pItems) {
            System.out.println("百分比:" + pContentLength + "已上传:" + pBytesRead + "字段编号:" + pItems);
        }
    });
    return servletFileUpload;
}

//3、正式解析表单中上传的文件,并将其存储在服务器上指定的位置
private String uploadParasRequest(ServletFileUpload upload, HttpServletRequest req, String uploadPath) {
    ServletRequestContext context = new ServletRequestContext(req);
    String msg = "";
    try {
        // 使用文件解析对象parseRequest,将表单中每一个input标签封装成FileItem对象
        // parseRequest(HttpServletRequest) 方法可以将通过表单中每一个HTML标签提交的数据封装成一个FileItem对象,然后以List列表的形式返回
        List fileItems = upload.parseRequest(context);
        for (FileItem fileItem : fileItems) {
            // 遍历,找到表单中每一个文件对应的上传数据
            if (fileItem.isFormField()) {
                // 判断中数据不是文件
                String name = fileItem.getFieldName();// 获取非文件的name属性
                String value = fileItem.getString("utf-8");// 获取非文件的value属性
                System.out.println(name + ":" + value);
            } else {// 是文件
                //===============1、处理文件:获取文上传的文件的文件名+文件类型===============
                String uploadFileName = fileItem.getName();//获取这个文件的名字
                if (uploadFileName.trim().equals("") || uploadFileName == null) {
                    //如果文件上传的名字为空
                    continue;// 跳过本次循环
                }
                // 获取上传文件名字,格式
                String fileName = uploadFileName.substring(uploadFileName.lastIndexOf("/") + 1);
                String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1);
                System.out.println("名字:" + fileName + "格式:" + fileExtName);
                //=====================2、处理文件存放地址:/WEB-INF/upload + 文件上传时生成的唯一的UUID===============
                //可以使用UUID(可以唯一识别的通用码),保证文件名唯一;UUID.randomUUID(),随机生成一个唯一的识别通用码;
                String uuidPath = UUID.randomUUID().toString();
                String realPath = uploadPath + "/" + uuidPath;
                File realPathFile = new File(realPath);
                //给每个文件创建一个对应的文件夹
                if (!realPathFile.exists()) {
                    realPathFile.mkdir();
                }
                //============================3、文件传输:配合工具类fileName+文件IO操作就可以实现文件存储在服务器上============================
                InputStream in = null;
                in = fileItem.getInputStream();
                FileOutputStream fos = new FileOutputStream(realPath + "/" + fileName);
                byte[] buffer = new byte[1024];
                int len = 0;
                while ((len = in.read(buffer)) > 0) {
                    fos.write(buffer, 0, len);
                }
                // 刷新、释放流
                fos.flush();
                in.close();
                fos.close();
                msg = "上传成功";
                fileItem.delete();// 上传成功,清空临时文件
            }
        }
    } catch (FileUploadException e) {
        throw new RuntimeException(e);
    } catch (UnsupportedEncodingException e) {
        throw new RuntimeException(e);
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
    return msg;
}
二、文件下载

在HttpServletResponse中已经写过,这里就在重复一遍。

2.1 步骤
  1. 要获取下载文件的路径
  2. 下载的文件名是啥?
  3. 设置想办法让浏览器能够支持下载我们需要的东西
  4. 获取下载文件的输入流
  5. 创建缓冲区
  6. 获取OutputStream对象
  7. 将FileOutputStream流写入到bufer缓冲区
  8. 使用OutputStream将缓冲区中的数据输出到客户端!
2.2 代码实现
// 指定浏览器字符集编码
response.setContentType("text/html;charset=UTF-8");
//1. 要获取下载文件的路径(路径中空格被替换成%20)
String path = this.getServletContext().getClassLoader().getResource("别错过(DJ阿卓版) - 程佳佳.flac").getPath();
//MIME格式解码器(将%20变成空格)
path = URLDecoder.decode(path, "UTF-8");
File file = new File(path);
System.out.println("文件路径:" + file);
//2. 获取下载文件名称,去掉中间包含的空格(MIME格式编码器会将空格变成+)
String name = path.substring(path.lastIndexOf("/") + 1).replace(" ", "");
System.out.println("文件名:" + name);
//3. 设置想办法让浏览器能够支持下载我们需要的东西
// MIME格式编码器解决浏览器中文乱码
response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(name, "UTF-8"));
//4. 获取下载文件的输入流
FileInputStream fis = new FileInputStream(file);
//5. 创建缓冲区
int len = 0;
byte[] bufer = new byte[1024];
//6. 获取OutputStream对象
ServletOutputStream out = response.getOutputStream();
//7. 将FileOutputStream流写入到bufer缓冲区
while ((len = fis.read(bufer)) > 0) {
//8. 使用OutputStream将缓冲区中的数据输出到客户端!
    out.write(bufer, 0, len);
}
//9.释放资源
fis.close();
out.close();
三、上传下载互动 3.1 思路
  1. jsp页面上传文件,servlet对文件保存,文件名、文件路径存入数据库。
  2. 点击jsp页面查询已保存文件,servlet查询数据库中保存的文件名、文件路径,jsp页面展示文件名,文件路径隐藏展示type=“hidden”。
  3. 点击文件名,数据发送servlet调用下载文件。
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1020913.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号