【JavaWeb学习笔记】18 - 文件上传下载

news2024/11/17 7:26:52

项目代码

https://github.com/yinhai1114/JavaWeb_LearningCode/tree/main/fileupdown

目录

文件上传

一、基本介绍

二、文件上传的基本原理

​编辑

三、文件上传应用实例

四、文件上传的注意细节

1.解决中文乱码问题

2.分割文件夹

3.防止重名

4.百度WebUploader

5.空目录构建问题

文件下载

一、文件下载原理分析

二、文件下载案例

三、文件下载注意事项细节


文件上传

一、基本介绍

1.文件的上传和下载,是常见的功能。

2.后面项目就使用了文件上传下载。

3.如果是传输大文件,一般用专门工具或者插件

4.文件上传下载需要使用到两个包,需要导入

二、文件上传的基本原理

最后http请求走到servlet

三、文件上传应用实例

四、文件上传的注意细节

1.解决中文乱码问题

            //解决接收到文件名是中文乱码问题
            servletFileUpload.setHeaderEncoding("utf-8");

2.分割文件夹

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.yinhai.utils;

import java.time.LocalDateTime;

public class WebUtils {
    public WebUtils() {
    }

    public static String getYearMonthDay() {
        LocalDateTime ldt = LocalDateTime.now();
        int year = ldt.getYear();
        int monthValue = ldt.getMonthValue();
        int dayOfMonth = ldt.getDayOfMonth();
        String yearMonthDay = year + "-" + monthValue + "-" + dayOfMonth + "/";
        System.out.println(yearMonthDay);
        return yearMonthDay;
    }
}

在创建目录的时候调用工具类返回日期

3.防止重名

//4. 将文件拷贝到fileRealPathDirectory目录
//   构建一个上传文件的完整路径 :目录+文件名
//   对上传的文件名进行处理, 前面增加一个前缀,保证是唯一即可, 不错
name = UUID.randomUUID().toString() + "_" +System.currentTimeMillis() + "_" + name;
String fileFullPath = fileRealPathDirectory + "/" +name;
fileItem.write(new File(fileFullPath));

4.百度WebUploader

一个完美的文件上传,要考虑的因素很多,比如断点续传、控制图片大小,尺寸,分片上传,防止恶意上传等,在项目中,可以考虑使用WebUploader组件(百度开发)
WebUploader API文档 - Web Uploader

5.空目录构建问题

文件上传,创建web/upload的文件夹,在tomcat启动时,没有在out目录下创建对应的upload文件夹,原因是tomcat对应空目录是不会在out下创建相应目录的,所以,只需在upload目录下,放一个文件即可这个是Idea + Tomcat的问题,实际开发不会存在

6.多文件上传,改变一下前端页面即可,数组是会默认拿出来的

文件下载

一、文件下载原理分析

二、文件下载案例

downloadServlet

package com.yinhai.servlet;

import com.sun.org.apache.bcel.internal.generic.NEW;
import com.yinhai.utils.WebUtils;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.UUID;

/**
 * @author 银小海
 * @version 1.0
 * @email yinhai14@qq.com
 */
@WebServlet(name = "FileUploadServlet",urlPatterns = "/fileUpload")
public class FileUploadServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("be invoked...");

        //1.判断是不是文件表单(enctype=“multipart/form-data”)
        if(ServletFileUpload.isMultipartContent(request)){
            System.out.println("OK! this is fileUpload!!!");
            //2. 创建 DiskFileItemFactory 对象, 用于构建一个解析上传数据的工具对象
            DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
            //3. 创建一个解析上传数据的工具对象
            /**
             *     表单提交的数据就是 input 元素
             *     <input type="file" name="pic" id="" value="2xxx.jpg" onchange="prev(this)"/>
             *     家居名: <input type="text" name="name"><br/>
             *     <input type="submit" value="上传"/>
             */
            ServletFileUpload servletFileUpload =
                    new ServletFileUpload(diskFileItemFactory);
            //解决接收到文件名是中文乱码问题
            servletFileUpload.setHeaderEncoding("utf-8");

            //4. 关键的地方, servletFileUpload 对象可以把表单提交的数据text/文件
            //   将其封装到 FileItem 文件项中
            //   如果我们不知道一个对象是什么结构[1.输出 2.debug 3. 底层自动看到]
            try {
                List<FileItem> list = servletFileUpload.parseRequest(request);
                System.out.println("list" + list);
                /*
                list[name=MIKU.jpg,StoreLocation=C:\Users\64301\Desktop\JAVA\apache-tomcat-8.0.50\temp\ upload_32df8824_18ca62f4c87__7f5a_00000000.tmp,
                size=294099bytes, isFormField=false, FieldName=pic,
                name=null,StoreLocation=C:\Users\64301\Desktop\JAVA\apache-tomcat-8.0.50\temp\ upload_32df8824_18ca62f4c87__7f5a_00000001.tmp,
                size=0bytes, isFormField=true, FieldName=name]

                 */
                //遍历并分别处理
                for (FileItem fileItem : list) {
                    //System.out.println("fileItem=" + fileItem);
                    //判断是不是一个文本=> 你是OOP程序员
                    if (fileItem.isFormField()) {//如果是true就是文本 input text
                        String name = fileItem.getString("utf-8");
                        // String name = fileItem.getName();
                        System.out.println("输入的名字=" + name);
                    } else {//是一个文件
                        //用一个方法
                        //获取上传的文件的名字
                        String name = fileItem.getName();
                        System.out.println("上传的文件名=" + name);

                        //把这个上传到 服务器的 temp下的文件保存到你指定的目录
                        //1.指定一个目录 , 就是我们网站工作目录下
                        String filePath = "/upload/";
                        //2.获取到完整目录
                        //C:\Users\64301\Desktop\JAVA\code\JavaWeb_LearningCode\out\artifacts\fileupdown_war_exploded\ upload\
                        String fileRealPath = request.getServletContext().getRealPath(filePath) + WebUtils.getYearMonthDay();
                        System.out.println(fileRealPath);
                        //3. 创建这个上传的目录=> 创建目录 => Java基础
                        // 一个工具类,可以返回 /2024-11-11/ 字符串
                        File fileRealPathDirectory = new File(fileRealPath);
                        if(!fileRealPathDirectory.exists()){//不存在就创建
                            boolean mkdirs = fileRealPathDirectory.mkdirs();
                            System.out.println("创建文件夹" + mkdirs);
                        }
                        //4. 将文件拷贝到fileRealPathDirectory目录
                        //   构建一个上传文件的完整路径 :目录+文件名
                        //   对上传的文件名进行处理, 前面增加一个前缀,保证是唯一即可, 不错
                        name = UUID.randomUUID().toString() + "_" +System.currentTimeMillis() + "_" + name;
                        String fileFullPath = fileRealPathDirectory + "/" +name;
                        fileItem.write(new File(fileFullPath));

                        //5. 提示信息
                        response.setContentType("text/html;charset=utf-8");
                        response.getWriter().write("上传成功~");

                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }else{
            System.out.println("Dont fileUpload...");
        }
    }

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

download.JSP 

<%--
  Created by IntelliJ IDEA.
  User: 银小海
  Date: 2023/12/26 Time: 22:32
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>文件下载</title>
    <base href="<%=request.getContextPath()+"/"%>>">
</head>
<body>
<h1>文件下载</h1>
<a href="fileDownload?name=Miku.jpg">点击下载Miku.jpg</a><br/><br/>
<a href="fileDownload?name=Rem.png">点击下载 Rem.png</a><br/><br/>
<%--<a href="fileDownload?name=高山流水.mp3">点击下载 高山流水.mp3</a><br/><br/>--%>
</body>
</html>

三、文件下载注意事项细节

1.文件下载,比较麻烦的就是文件名中文处理

        if (request.getHeader("User-Agent").contains("Firefox")) {
            // 火狐 Base64编码
            response.setHeader("Content-Disposition", "attachment; filename==?UTF-8?B?" +
                    new BASE64Encoder().encode(downLoadFileName.getBytes("UTF-8")) + "?=");
        } else {
            // 其他(主流ie/chrome)使用URL编码操作
            response.setHeader("Content-Disposition", "attachment; filename=" +
                    URLEncoder.encode(downLoadFileName, "UTF-8"));
        }

2.因此,老师在代码中,针对不同浏览器做了处理

3.对于网站的文件,很多文件使用另存为即可下载,对于大文件(文档,视频),会使用专业的下载工具(迅雷、百度)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1338904.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Doris:为企业数据查询加速

Doris是一款由百度开发的开源数据仓库查询引擎&#xff0c;它能够帮助用户高效地查询和分析大规模数据。Doris具有高性能、易用性强、可扩展性高等特点&#xff0c;让数据分析变得更加简单。 二、场景&#xff1a; Doris适用于各种数据仓库场景&#xff0c;无论是大数据分析、…

搭建WebDAV服务+cpolar内网穿透公网同步Zotero科研文献

文章目录 一、Zotero安装教程二、群晖NAS WebDAV设置三、Zotero设置四、使用公网地址同步Zotero文献库五、使用永久固定公网地址同步Zotero文献库 Zotero 是一款全能型 文献管理器,可以 存储、管理和引用文献&#xff0c;不但免费&#xff0c;功能还很强大实用。 ​ Zotero 支…

图灵日记之java奇妙历险记--类和对象

目录 类的定义和使用类的定义格式 类的实例化类和对象的说明 this引用this引用的特性 对象的构造及初始化就地初始化构造方法 封装包导入包中的类自定义包 static成员static修饰成员变量static修饰成员方法 代码块代码块概念及分类构造代码块静态代码块 匿名对象 类的定义和使用…

Python入门学习篇(十)——函数定义函数传参方式

1 相关定义和概念 1.1 函数的理解 一段被封装的可以重复调用的代码。 1.2 函数定义语法结构 def 函数名(形参1,形参2):要封装的逻辑代码 # 注意:函数可以有返回值也可以没有返回值,没有返回值的结果是None1.3 函数调用的语法结构 函数名(形参1,形参2)1.4 简单实例 1.4.1 …

不浪费时间,昂首资本1分钟如何快速学习MT4价差

不要浪费时间在手工计算上&#xff0c;昂首资本解释一下如何快速学习MT4价差&#xff0c;。 想要在MT4中输入交易时&#xff0c;需要在交易窗口中设置未来交易的参数。在同一个窗口中&#xff0c;可以看到卖价和买价。如果在上面的例子中比较这两个价格&#xff0c;就会发现两…

如何查看NX UI对话框内的控件(使用UIFW侦查)

一、概述 在NX二次开发中有很多命令从界面上看起开相似&#xff0c;但实质确不同&#xff0c;个人人为一是出于对软件产权的保护&#xff0c;增加二次开发的难度&#xff0c;二是由于NX在不断地发展和版本交替中为了保留老用户的操作习惯&#xff0c;故意用新控件做成老控件的…

LeetCode刷题--- N 皇后

个人主页&#xff1a;元清加油_【C】,【C语言】,【数据结构与算法】-CSDN博客 个人专栏 力扣递归算法题 http://t.csdnimg.cn/yUl2I 【C】 http://t.csdnimg.cn/6AbpV 数据结构与算法 ​​​​​​http://t.csdnimg.cn/hKh2l 前言&#xff1a;这个专栏主要讲述递归…

模式识别与机器学习-特征选择和提取

模式识别与机器学习-特征选择和提取 特征选择一些距离测度公式独立特征的选择准则一般特征的散布矩阵准则 离散K-L变换 谨以此博客作为复习期间的记录。 常见分类问题的流程&#xff0c;数据预处理和特征选择提取时机器学习环节中最重要的两个流程。这两个环节直接决定了最终性…

数模学习02-Matlab基础知识入门

先把matlab下载好。然后你就会发现电脑有少了几十个GB。服啦~ 修改字体 字体真的是太小了&#xff0c;其实我无论是使用什么编辑器我一般都会先改字体&#xff0c;字体在开始中有一个预设&#xff0c;可以修改字体&#xff0c;这样眼睛看着也会舒服一点 命令行窗口的使用 这…

亚马逊美国站ASTM F2613儿童折叠椅和凳子强制性安全标准

ASTM F2613折叠椅和凳子安全标准 美国消费品安全委员会&#xff08;CPSC&#xff09;发布的ASTM F2613儿童折叠椅和凳子的强制性安全标准&#xff0c;已于2020年7月6日生效&#xff0c;并被纳入联邦法规《16 CFR 1232儿童折叠椅和凳子安全标准》。 亚马逊要求在美国站上架的儿…

GaussDB元命令使用指导

所谓元命令就是在gsql里输入的任何以不带引号的反斜杠开头的命令。本课程通过实际使用gsql实践&#xff0c;介绍GaussDB数据库gsql所提供的元命令。 本课程仅展示基础的元命令使用。 一、操作步骤 步骤1 使用gsql连接到GaussDB实例。 gsql工具使用-d参数指定目标数据库名…

何时为 SEO 创建本地化文件夹和页面

您可以为新网站创建主题支柱页面吗&#xff1f; 您网站的使用年限与您如何构建内容和文件夹无关紧要。在重建已有 10 年历史的域或启动新 URL 时&#xff0c;可以做到这一点。 您应该始终构建您的网站&#xff0c;以便它帮助最终用户了解网站的层次结构&#xff0c;并显示该部…

详解Vue3中的插槽(slot)

本文主要介绍Vue3中的插槽&#xff08;slot&#xff09;。 目录 一、在普通写法中使用插槽&#xff08;slot&#xff09;作用域插槽默认插槽 二、在setup写法中使用插槽&#xff1a;注意事项 在Vue3中&#xff0c;插槽&#xff08;slot&#xff09;是一种用于在父组件中向子组件…

【2】Docker Compose编排

Docker Compose 使用 Docker 帮助我们解决服务的打包安装的问题&#xff0c;随着而来的问题就是服务过多的带来如下问题&#xff1a; 多次使用 Dockerfile、Build、Image 命令或者 DockerHub 拉取 Image&#xff1b;需要创建多个 Container&#xff0c;多次编写启动命令&…

Python——yolov8识别车牌2.0

目录 一、前言 二、关于项目UI 2.1、修改界面内容的文本 2.2、修改界面的图标和图片 三、项目修改地方 四、其他配置问题 一、前言 因为后续有许多兄弟说摄像头卡顿&#xff0c;我在之前那个MATS上面改一下就可以了&#xff0c;MAST项目&#xff1a;基于YOLOv8的多端车流检…

51 单片机基础

一、51 单片机 开发环境配置&#xff0c;vscodeSDCC 编辑器、编译器 最常用的集成开发环境 keil c51 1、vscode SDCC 开发环境搭建 vscode 插件&#xff08; 或者 PlatformIO IDE&#xff09; EIDE 的使用&#xff1a;详细自学 PlatformIO IDE&#xff1a;详细自学 vsc…

C#高级 02异步编程

基础知识 1.什么是异步任务 包含了异步任务的各种状态的一个引用类型 1)正在运行、完成、结果、报错等 2)另有ValueTask值类型版本对于异步任务的抽象 1)开启异步任务后&#xff0c;当前线程并不会阻塞&#xff0c;而是可以去做其他事情 2)异步任务&#xff08;默认&#xff…

HTTP是怎么泄露账户密码的?

近几年,互联网发生着翻天覆地的变化,尤其是我们一直习以为常的HTTP协议,在逐渐的被HTTPS协议所取代,在浏览器、搜索引擎、CA机构、大型互联网企业的共同促进下,互联网迎来了“HTTPS加密时代”,HTTPS将在未来的几年内全面取代HTTP成为传输协议的主流。 那么HTTPS和HTTP的区别在…

2023年总结:反复纠结与成长的一年

前言 这是我第五年写年度总结&#xff1a; 《2022年总结&#xff1a;道阻且长&#xff0c;行则将至》 《2021年总结&#xff1a;前路有光&#xff0c;初心莫忘》 《2020年总结&#xff0c;所有努力只为一份期待》 《2019年总结&#xff0c;平凡的我仍在平凡的生活》 现在…

LeetCode206反转链表(java实现)

今天带来的题目解析是leetcode206&#xff0c;反转链表&#xff0c;我们来看下题目描述 如何实现链表的反转呢&#xff1f;我在这里提供的思路是双指针的思路。 具体的思路如下&#xff1a; 假设我们的原链表如下 首先定义一个指针pre&#xff0c;用于指向head之前的位置&am…