Servlet的文件上传下载

Servlet的文件上传|下载

二、文件上传实现

2.1实现思路
  1. 需要使用到Commons-FileUpload组件
  2. 需要将jsp页面form表单的enctype属性值设置为“multipart/form-data”,
  3. Servlet中使用IO流实现文件的上传
2.2、实现过程
2.2.1新建web项目导入jar包
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.4</version>
</dependency>
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.6</version>
</dependency>
2.2.2、编写页面

在webapp下编写upload.jsp页面,用于提供文件上传的form表单,需要注意的是,form表单的enctype属性值要设置为“multipart/form-data”,method属性值要设置为“post”,并将action属性值设置为“upServlet”

<!--
    文件上传
    1.准备表单
    2.设置表单的提交类型 method = "post"
    3.设置表单类型为文件上传表单 enctype=“multipart/form-data”
    4.设置文件提交的地址
    5.准备表单元素
        1.普通的表单项 type="text
        2.文件项 type="file"
    6.设置表单元素的name属性值(表单提交一定要设置表元素的name属性值,否则后台无法接收数据!)
 -->
<form action="upServlet" method="post"
      enctype="multipart/form-data">
    <table width="600px">
        <tr>
            <td>上传者</td>
            <td><input type="text" name="name" /></td>
        </tr>
        <tr>
            <td>上传文件</td>
            <td><input type="file" name="myfile"></td>
        </tr>
        <tr>
            <td colspan="2"><input type="submit" value="上传" /></td>
        </tr>
    </table>
</form>

在这里插入图片描述

2.2.3、创建Servlet

在web项目的java文件夹下创建包com.kdf.upload,在该包中新建一个名称为UploadServlet的类,用于获取表单及其上传文件的信息。

package com.kdf.upload;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import org.apache.commons.fileupload.*;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
//上传文件的Servlet类
@WebServlet(name = "UploadServlet",urlPatterns = "/upServlet")
//该注解用于标注文件上传的Servlet
@MultipartConfig
public class UploadServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    public void doGet(HttpServletRequest request,
                      HttpServletResponse response)throws ServletException, IOException {
        try {
            //设置ContentType字段值
            response.setContentType("text/html;charset=utf-8");
            // 创建DiskFileItemFactory工厂对象
            DiskFileItemFactory factory = new DiskFileItemFactory();
            //设置文件缓存目录,如果该目录不存在则新创建一个
            File f = new File("E:\\TempFolder");
            if (!f.exists()) {
                f.mkdirs();
            }
            // 设置文件的缓存路径
            factory.setRepository(f);
            // 创建 ServletFileUpload对象
            ServletFileUpload fileupload = new ServletFileUpload(factory);
            //设置字符编码
            fileupload.setHeaderEncoding("utf-8");
            // 解析 request,得到上传文件的FileItem对象
            List<FileItem> fileitems = fileupload.parseRequest(request);
            //获取字符流
            PrintWriter writer = response.getWriter();
            // 遍历集合
            for (FileItem fileitem : fileitems) {
                // 判断是否为普通字段
                if (fileitem.isFormField()) {
                    // 获得字段名和字段值
                    String name = fileitem.getFieldName();
                    if(name.equals("name")){
                        //如果文件不为空,将其保存在value中
                        if(!fileitem.getString().equals("")){
                            String value = fileitem.getString("utf-8");
                            writer.print("上传者:" + value + "<br />");
                        }
                    }
                } else {
                    // 获取上传的文件名
                    String filename = fileitem.getName();
                    //处理上传文件
                    if(filename != null && !filename.equals("")){
                        writer.print("上传的文件名称是:" + filename + "<br />");
                        // 截取出文件名
                        filename = filename.substring(filename.lastIndexOf("\\") + 1);
                        // 文件名需要唯一
                        filename = UUID.randomUUID().toString() + "_" + filename;
                        // 在服务器创建同名文件
                        String webPath = "/upload/";
                        //将服务器中文件夹路径与文件名组合成完整的服务器端路径
                        String filepath = getServletContext()
                                .getRealPath(webPath + filename);
                        // 创建文件
                        File file = new File(filepath);
                        file.getParentFile().mkdirs();
                        file.createNewFile();
                        // 获得上传文件流
                        InputStream in = fileitem.getInputStream();
                        // 使用FileOutputStream打开服务器端的上传文件
                        FileOutputStream out = new FileOutputStream(file);
                        // 流的拷贝
                        byte[] buffer = new byte[1024];//每次读取1个字节
                        int len;
                        //开始读取上传文件的字节,并将其输出到服务端的上传文件输出流中
                        while ((len = in.read(buffer)) > 0)
                            out.write(buffer, 0, len);
                        // 关闭流
                        in.close();
                        out.close();
                        // 删除临时文件
                        fileitem.delete();
                        writer.print("上传文件成功!<br />");
                    }
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
        doGet(request, response);
    }
}

启动项目,选择文件进行上传。

在这里插入图片描述

在这里插入图片描述

三、文件下载

3.1download.jsp
<a href=
           "http://localhost:8080/DownloadServlet?filename=1.png">
    文件下载</a>
</body>
3.2servlet
package com.kdf.upload;
import java.io.*;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
@WebServlet(name = "DownloadServlet",urlPatterns = "/DownloadServlet")
public class DownloadServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    public void doGet(HttpServletRequest request, HttpServletResponse
            response) throws ServletException, IOException {
        //设置ContentType字段值
        response.setContentType("text/html;charset=utf-8");
        //获取所要下载的文件名称
        String filename = request.getParameter("filename");
        //下载文件所在目录
        String folder = "/download/";
        // 通知浏览器以下载的方式打开
        response.addHeader("Content-Type", "application/octet-stream");
        response.addHeader("Content-Disposition",
                "attachment;filename="+filename);
        folder=folder+filename;
        // 通过文件流读取文件
        InputStream in = getServletContext().getResourceAsStream(folder);
        // 获取response对象的输出流
        OutputStream out = response.getOutputStream();
        byte[] buffer = new byte[1024];
        int len;
        //循环取出流中的数据
        while ((len = in.read(buffer)) != -1) {
            out.write(buffer, 0, len);
        }
    }
    public void doPost(HttpServletRequest request, HttpServletResponse
            response) throws ServletException, IOException {
        doGet(request, response);
    }
}

在这里插入图片描述

一、文件上传原理

要实现Web开发中的文件上传功能,通常需完成两步操作:

一是在Web项目的页面中添加上传输入项

二是在Servlet中读取上传文件的数据,并保存到目标路径中。
由于大多数文件的上传都是通过表单的形式提交给服务器的,因此,要想在程序中实现文件上传功能,首先要创建一个用于提交上传文件的表单页面。在表单页面中,需要使用标签在jsp页面中添加文件上传输入项。

1.1、文件域

标签的使用。

  • 必须要设置input输入项的name属性,否则浏览器将不会发送上传文件的数据。
  • 必须把将表单页面的method属性设置为post方式,enctype属性设置为“multipart/form-data”类型。
<%--指定表单数据的enctype属性以及提交方式--%>
<form enctype="multipart/form-data" method="post">
	<%--指定标记的类型和文件域的名称--%>
	选择上传文件:<input type="file" name="myfile"/><br />
</form>

1.2、commons-fileUpload

当浏览器通过表单提交上传文件时,文件数据都附带在HTTP请求消息体中,并且采用MIME类型(多用途互联网邮件扩展类型)进行描述,在后台可以使用request对象提供的getInputStream()方法读取客户端提交过来的数据。

但由于用户可能会同时上传多个文件,而在Servlet端直接读取上传数据,并分别解析出相应的文件数据是一项非常麻烦的工作。为了方便处理用户上传的数据,Apache组织提供了一个开源组件Commons- FileUpload,该组件可以方便地将“multipart/form-data”类型请求中的各种表单域解析出来,并实现一个或多个文件的上传,文件上传的原理如下图所示。
在这里插入图片描述

1.3、FileItem接口

FileItem接口主要用于封装单个表单字段元素的数据,一个表单字段元素对应一个FileItem对象。Commons-FileUpload组件在处理文件上传的过程中,将每一个表单域(包括普通的文本表单域和文件域)封装在一个FileItem对象中。常用方法如下表所示:

方法声明功能描述
boolean isFormField()isFormField()方法用于判断FileItem类对象封装的数据是一个普通文本表单字段,还是一个文件表单字段,如果是普通文本表单字段则返回true,否则返回false。
String getName()getName()方法用于获取文件上传字段中的文件名。如果FileItem类对象对应的是普通文本表单字段,getName()方法将返回null,否则,只要浏览器将文件的字段信息传递给服务器,getName()方法就会返回一个字符串类型的结果,如C:\Sunset.jpg。
String getFieldName()getFieldName()方法用于获取表单字段元素描述头的name属性值,也是表单标签name属性的值。例如“name=file1”中的“file1”。
void write(File file)write()方法用于将FileItem对象中保存的主体内容保存到某个指定的文件中。如果FileItem对象中的主体内容是保存在某个临时文件中,那么该方法顺利完成后,临时文件有可能会被清除。另外,该方法也可将普通表单字段内容写入到一个文件中,但它主要用于将上传的文件内容保存到本地文件系统中。
String getString()getString()方法用于将FileItem对象中保存的数据流内容以一个字符串形式返回。它有两个重载的定义形式:①public String getString()②public String getString(java.lang.String encoding)前者使用默认的字符集编码将主体内容转换成字符串,后者使用参数指定的字符集编码将主体内容转换成字符串。
String getContentType()getContentType()方法用于获得上传文件的类型,即表单字段元素描述头属性“Content-Type”的值,如“image/jpeg”。如果FileItem类对象对应的是普通表单字段,该方法将返回null。
1.4、DiskFileItemFactory类

DiskFileItemFactory类用于将请求消息实体中的每一个文件封装成单独的FileItem对象。如果上传的文件比较小,将直接保存在内存中,如果上传的文件比较大,则会以临时文件的形式,保存在磁盘的临时文件夹中。默认情况下,不管文件保存在内存还是磁盘临时文件夹,文件存储的临界值是10240字节,即10KB。

方法声明功能描述
DiskFileItemFactory()采用默认临界值和系统临时文件夹构造文件项工厂对象
DiskFileItemFactory(int sizeThreshold,File repository)采用参数指定临界值和系统临时文件夹构造文件项工厂对象

DiskFileItemFactory(int sizeThreshold,File repository)构造方法传递两个参数,第一个参数sizeThreshold表示文件保存在内存还是磁盘临时文件夹中的临界值,第二个参数repository表示临时文件的存储路径。

1.5、ServletFileUpload类

ServletFileUpload类是Apache组件处理文件上传的核心高级类,通过调用parseRequest(HttpServletRequest) 方法可以将HTML中每个表单提交的数据封装成一个FileItem对象,然后以List列表的形式返回。

方法声明功能描述
ServletFileUpload()构造一个未初始化的ServletFileUpload实例对象
ServletFileUpload(FileItemFactory fileItemFactory)根据参数指定的FileItemFactory 对象创建一个ServletFileUpload对象

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

weblogic oracle数据源配置

在weblogic console中配置jdbc oracle数据源 1. base_domain->Service->DataSources 在Summary of JDBC Data Sources中&#xff0c;点击New, 选择【Generic Data Source】通用数据源。 2. 设置数据源Name和JNDI name 注&#xff1a;设置的JNDI Name是Java AP中连接…

数据可视化高级技术Echarts(桑基图入门)

目录 一、什么是桑基图 二、基本特征 三、设计注意事项 四、使用Echarts进行初级绘制 1.首先不能忘记五个基本步骤 2.绘制的时需要将图像类型series.type设定为sankey类型。 一、什么是桑基图 桑基图&#xff08;Sankey diagram&#xff09;&#xff0c;即桑基能量分流图&…

EI级 | Matlab实现TCN-LSTM-MATT、TCN-LSTM、TCN、LSTM多变量时间序列预测对比

EI级 | Matlab实现TCN-LSTM-MATT、TCN-LSTM、TCN、LSTM多变量时间序列预测对比 目录 EI级 | Matlab实现TCN-LSTM-MATT、TCN-LSTM、TCN、LSTM多变量时间序列预测对比预测效果基本介绍程序设计参考资料 预测效果 基本介绍 【EI级】Matlab实现TCN-LSTM-MATT、TCN-LSTM、TCN、LSTM…

Grok-1.5 Vision:X AI发布突破性的多模态AI模型,超越GPT 4V

在人工智能领域&#xff0c;多模态模型的发展一直是科技巨头们竞争的焦点。 近日&#xff0c;马斯克旗下的X AI公司发布了其最新的多模态模型——Grok-1.5 Vision&#xff08;简称Grok-1.5V&#xff09;&#xff0c;这一模型在处理文本和视觉信息方面展现出了卓越的能力&#x…

Elasticsearch分布式搜索

实用篇-ES-环境搭建 ES是elasticsearch的简称。我在SpringBoot学习 数据层解决方案 的时候&#xff0c;写过一次ES笔记&#xff0c;可以结合一起看一下。 之前在SpringBoot里面写的相关ES笔记是基于Windows的&#xff0c;现在我们是基于docker容器来使用&#xff0c;需要你们提…

突破编程_前端_SVG(ellipse 椭圆形)

1 ellipse 元素的基本属性和用法 ellipse 元素用于创建椭圆形状。它具有一系列的基本属性&#xff0c;允许自定义椭圆的外观和位置。以下是一些 ellipse 元素的基本属性和用法&#xff1a; &#xff08;1&#xff09;基本属性 cx 和 cy&#xff1a;这两个属性定义了椭圆中心…

【CicadaPlayer】prepare和start的触发和异步处理

主线程可以直接用SuperMediaPlayer 但SuperMediaPlayer 的处理是异步的。实际上msgproc的目的在于异步处理外部请求 例如,启动后会先设置view,这个与播放流程无关,但是是必须要让播放器拥有的。用户点击prepare是直接调用SuperMediaPlayer的Prepare接口,才会触发url的设置 …

数据结构--栈,队列,串,广义表

3.栈 &#xff08;先进后出&#xff09; 栈是一种特殊的线性表&#xff0c;只能从一端插入或删除操作。 4.队列 4.1 4.1.1初始化 4.1.2判断队列是否为空 4.1.3判断队列是否为满 4.1.4入队 4.1.5出队 4.1.6打印队列 4.1.7销毁队列 5.串 5.1 串的定义 由零个或者任意多…

最新AI创作系统ChatGPT网站源码AI绘画,GPTs,AI换脸支持,GPT联网提问、DALL-E3文生图

一、前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图文教程吧。已支持GPT…

VMware安装Linux虚拟机(rocky9)

软件准备&#xff1a; VMware虚拟机ISO系统镜像文件 选择创建虚拟机→典型→下一步→点击稍后安装操作系统 选择Linux系统和对应版本 输入虚拟机名称和选择保存位置 设置磁盘大小 根据需要自定义硬件配置→完成 然后点击编辑虚拟机设置→CD/DVD→选择ISO镜像 然后开启虚拟机→…

vue2 二次封装element 组件,继承组件原属性,事件,插槽 示例

测试页面代码 这里主要记录如何封装element的el-input 并且封装后具有el-input原本的属性 事件 插槽 下面为测试页面即组件调用 <script> import CustomInput from /components/CustomInput.vue;export default {name: TestPage,components: { CustomInput },data() …

【洛谷 P4017】最大食物链计数 题解(深度优先搜索+动态规划+邻接表+记忆化搜索+剪枝)

最大食物链计数 题目背景 你知道食物链吗&#xff1f;Delia 生物考试的时候&#xff0c;数食物链条数的题目全都错了&#xff0c;因为她总是重复数了几条或漏掉了几条。于是她来就来求助你&#xff0c;然而你也不会啊&#xff01;写一个程序来帮帮她吧。 题目描述 给你一个…

【CSS面试题】Flex实现九宫格

考察知识&#xff1a; flex布局 水平垂直居中的实现 初始效果 代码关键&#xff1a;给父盒子添加以下属性 flex-wrap: wrap; /* 允许换行 */justify-content: space-around; /* 主轴对齐方式 */align-content: space-around; /* 多行在侧轴上的对齐方式 */<!DOCTYPE html&…

如何让Nrf connect、EFR connect直接显示特征值数据及其单位

效果如图&#xff1a;app直接显示了我的温度&#xff0c;并且有两位小数&#xff0c;还有温度单位。这是怎么做到的呢&#xff1f; 这次我们仍以TLS8258为例&#xff0c;当然如果是其他蓝牙芯片&#xff0c;配置方式也是大差不差&#xff0c;规则一样的。 #define GATT_CHARA…

租用马来西亚服务器:稳定高效的网络选择

马来西亚首都是吉隆坡。作为一个新兴的多元化经济国家&#xff0c;也属于亚洲四小龙之一。地理位置优越&#xff0c;中间隔着南中国海。一部分是北接泰国的位于马来半岛的西马来西亚&#xff0c;另一部分则是东马来西亚&#xff0c;在婆罗洲岛的北部。这种地理位置有利于促进该…

[Java EE] 计算机工作原理与操作系统简明概要

1. 计算机工作原理 1.1 生活中常见的计算机 计算机分为通用计算机和专用计算机,计算机并不单单指的是电脑,还有我们平时使用的手机,ipad,智能手表等终端设备都是计算机.还有我们用户不常见的计算机,比如服务器. 还有许多嵌入式设备(针对特定场景定制的"专用计算机"…

系统学c#:1、基础准备(软件下载与安装)

一、Vs软件下载与安装 访问Visual Studio官方网站&#xff1a; https://visualstudio.microsoft.com/zh-hans/downloads 下载Visual Studio 运行exe文件&#xff0c;点击“继续” 初始文件安装完成后选择我们需要安装的项&#xff0c;并勾选好必要的单个组件&#xff0c;设…

cookie与session及其区别

一、cookie 1. 为什么需要cookie&#xff1f; web程序使用HTTP协议进行传输&#xff0c;而HTTP协议是无状态的协议&#xff08;即对事务处理无记忆性&#xff0c;如果后续处理需要使用前面的信息&#xff0c;只能重传&#xff0c;导致每次连接传送的数据量增大&#xff09;。c…

maven3.9+下载安装

maven介绍 Maven 是一个项目管理和理解工具&#xff0c;它基于项目对象模型&#xff08;POM&#xff09;概念。Maven 可以帮助开发者定义项目结构、依赖关系、构建过程以及其他任务。它主要用于 Java 项目&#xff0c;但也可以用于其他类型的项目。Maven 的主要目标是简化构建…

单元测试四大过程

单元测试四大过程&#xff08;蓝桥课学习笔记&#xff09; 单元测试过程 单元测试是软件测试过程中的一个关键环节&#xff0c;它与集成测试、系统测试一样&#xff0c;分为测试策划、测试设计、测试执行和测试总结几个阶段。 单元测试过程中每个阶段需要完成的主要工作如下&…