在Servlet中使用开源fileupload包实现文件上传功能

2023-10-31

当我们在 HTML 表单中选择本地文件之后点击“提交”按钮则会将文件上传到服务器中,此时该 HTTP 请求正文的数据类型就是 multipart/form-data 型的。而在 Servlet 技术中,该 HTTP 请求会被 Servlet 容器(如 Tomcat)包装成 HttpServletRequest 对象,再由端所请求的相应 Servlet 进行处理。

但是,如果此时我们在服务器端编写的 Servlet 一点点地解析这个 HTTP 请求,分离出其中的文本表单和上传的文件类型,这未免有点低效。于是,我们可以使用 Apache 开源上传软件包 fileupload 来简化这一过程,直接使用即可。下载地址:http://commons.apache.org/fileupload/

在 fileupload 包中, HTTP 请求中的复杂表单元素都被看做一个 FileItem 对象;FileItem 对象必须由 ServletFileUpload 类中的 parseRequest() 方法解析 HTTP 请求(即被包装之后的 HttpServletRequest 对象)出来,即分离出具体的文本表单和上传文件;而 ServletFileUpload 对象的创建需要依赖于 FileItemFactory 工厂将获得的上传文件 FileItem 对象保存至服务器硬盘,即 DiskFileItem 对象。

呼…把这个 fileupload 包中的关系讲得那么乱,最好还是自己看下载下来的帮助文档。不过,推荐一个免费的 Java 反编译器 JD-GUI ,用它能够很轻松地打开 .jar 文件,除了源代码中的注释,其他的一览无遗,很好用啊。下载地址:http://java.decompiler.free.fr/?q=jdgui

好吧,我们的程序要求:

1、提供一个 HTML 文件,用户可在相应表单中选择需要上传的文件;

2、编写一个名叫 UploadServlet 的Servlet 文件,主要功能是解析上面 HTML 表单所提交的 HTTP 请求,把普通的文本域和文件域分离开来;

3、UploadServlet 根据 web.xml 配置文件中的初始化参数确定好需要在 Web 服务器存放该文件的目录,将上传的文件写入到该存放目录中,在我的这里我把上传的文件保存到 F:\java\JavaWeb\ch05\uploadFile 目录中,而 F:\java\JavaWeb\ch05\temp 目录则用作该 Web 应用的临时目录。

程序代码:

upload.html 文件

 
 
  1. <html> 
  2.     <head>  <title>Servlet 上传文件</title></head> 
  3.     <body > 
  4.       <form name="uploadForm" method="POST" 
  5.         enctype="MULTIPART/FORM-DATA" 
  6.         action="upload"> 
  7.  
  8.         User Name:<input type="text" name="username" size="30"/> 
  9.         Upload File1:<input type="file" name="file1" size="30"/> 
  10.         Upload File2:<input type="file" name="file2" size="30"/>   
  11.         <input type="submit" name="submit" value="上传"> 
  12.         <input type="reset" name="reset" value="重置"> 
  13.       </form> 
  14.     </body> 
  15. </html> 

UploadServlet.java 文件

 
 
  1. import javax.servlet.*;  
  2. import javax.servlet.http.*;  
  3. import java.io.*;  
  4. import java.util.*;  
  5. import org.apache.commons.fileupload.*;  
  6. import org.apache.commons.fileupload.servlet.*;  
  7. import org.apache.commons.fileupload.disk.*;  
  8.  
  9. // Servlet 文件上传  
  10. public class UploadServlet extends HttpServlet  
  11. {  
  12.     private String filePath;    // 文件存放目录  
  13.     private String tempPath;    // 临时文件目录  
  14.  
  15.     // 初始化  
  16.     public void init(ServletConfig config) throws ServletException  
  17.     {  
  18.         super.init(config);  
  19.         // 从配置文件中获得初始化参数  
  20.         filePath = config.getInitParameter("filepath");  
  21.         tempPath = config.getInitParameter("temppath");  
  22.  
  23.         ServletContext context = getServletContext();  
  24.  
  25.         filePath = context.getRealPath(filePath);  
  26.         tempPath = context.getRealPath(tempPath);  
  27.         System.out.println("文件存放目录、临时文件目录准备完毕 ...");  
  28.     }  
  29.       
  30.     // doPost  
  31.     public void doPost(HttpServletRequest req, HttpServletResponse res)  
  32.         throws IOException, ServletException  
  33.     {  
  34.         res.setContentType("text/plain;charset=gbk");  
  35.         PrintWriter pw = res.getWriter();  
  36.         try{  
  37.             DiskFileItemFactory diskFactory = new DiskFileItemFactory();  
  38.             // threshold 极限、临界值,即硬盘缓存 1M  
  39.             diskFactory.setSizeThreshold(4 * 1024);  
  40.             // repository 贮藏室,即临时文件目录  
  41.             diskFactory.setRepository(new File(tempPath));  
  42.           
  43.             ServletFileUpload upload = new ServletFileUpload(diskFactory);  
  44.             // 设置允许上传的最大文件大小 4M  
  45.             upload.setSizeMax(4 * 1024 * 1024);  
  46.             // 解析HTTP请求消息头  
  47.             List fileItems = upload.parseRequest(req);  
  48.             Iterator iter = fileItems.iterator();  
  49.             while(iter.hasNext())  
  50.             {  
  51.                 FileItem item = (FileItem)iter.next();  
  52.                 if(item.isFormField())  
  53.                 {  
  54.                     System.out.println("处理表单内容 ...");  
  55.                     processFormField(item, pw);  
  56.                 }else{  
  57.                     System.out.println("处理上传的文件 ...");  
  58.                     processUploadFile(item, pw);  
  59.                 }  
  60.             }// end while()  
  61.  
  62.             pw.close();  
  63.         }catch(Exception e){  
  64.             System.out.println("使用 fileupload 包时发生异常 ...");  
  65.             e.printStackTrace();  
  66.         }// end try ... catch ...  
  67.     }// end doPost()  
  68.  
  69.  
  70.     // 处理表单内容  
  71.     private void processFormField(FileItem item, PrintWriter pw)  
  72.         throws Exception  
  73.     {  
  74.         String name = item.getFieldName();  
  75.         String value = item.getString();          
  76.         pw.println(name + " : " + value + "\r\n");  
  77.     }  
  78.       
  79.     // 处理上传的文件  
  80.     private void processUploadFile(FileItem item, PrintWriter pw)  
  81.         throws Exception  
  82.     {  
  83.         // 此时的文件名包含了完整的路径,得注意加工一下  
  84.         String filename = item.getName();         
  85.         System.out.println("完整的文件名:" + filename);  
  86.         int index = filename.lastIndexOf("\\");  
  87.         filename = filename.substring(index + 1, filename.length());  
  88.  
  89.         long fileSize = item.getSize();  
  90.  
  91.         if("".equals(filename) && fileSize == 0)  
  92.         {             
  93.             System.out.println("文件名为空 ...");  
  94.             return;  
  95.         }  
  96.  
  97.         File uploadFile = new File(filePath + "/" + filename);  
  98.         item.write(uploadFile);  
  99.         pw.println(filename + " 文件保存完毕 ...");  
  100.         pw.println("文件大小为 :" + fileSize + "\r\n");  
  101.     }  
  102.       
  103.     // doGet  
  104.     public void doGet(HttpServletRequest req, HttpServletResponse res)  
  105.         throws IOException, ServletException  
  106.     {  
  107.         doPost(req, res);  
  108.     }  

web.xml 文件

 
 
  1. <?xml version="1.0" encoding="gb2312"?> 
  2. <web-app xmlns="http://java.sun.com/xml/ns/j2ee" 
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  4.     xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" 
  5.     version="2.4"> 
  6.  
  7.     <servlet> 
  8.         <servlet-name>UploadServlet</servlet-name> 
  9.         <servlet-class>UploadServlet</servlet-class> 
  10.  
  11.         <init-param> 
  12.             <param-name>filepath</param-name> 
  13.             <param-value>uploadFile</param-value> 
  14.         </init-param> 
  15.         <init-param> 
  16.             <param-name>temppath</param-name> 
  17.             <param-value>temp</param-value> 
  18.         </init-param> 
  19.     </servlet>      
  20.  
  21.     <servlet-mapping> 
  22.         <servlet-name>UploadServlet</servlet-name> 
  23.         <url-pattern>/upload</url-pattern> 
  24.     </servlet-mapping> 
  25.  
  26. </web-app> 

 

程序运行过程截图:(在 web.xml 文件中我们把UploadServlet 映射为 upload

1、启动 Tomcat ,在浏览器输入 URL 并填写 HTML 表单,如下:

uploadServlet01

2、点击“上传”,发出一个包含了上传文件的复杂 HTTP 请求,由 UploadServlet 进行处理:

先看下 Tomcat 的控制台输出信息:

uploadServlet02

再看一下浏览器的相应输出:

uploadServlet03

最后看上传的文件是否被被保存在指定的目录中:

uploadServlet04

嗯,文件目录和文件保存时间都正确,就是文件大小忘了转化一下…(*^__^*) …

小结:

1、使用开源的 fileupload 包为我们在 UploadServlet 代码中显式地用繁杂的 request.getParameter(“username”) 语句来获取 HTTP 请求所包含的表单值;

2、而且还省去了我们在 UploadServlet 中自己编写判断表单是否是文件或文本类型的代码;

3、更重要的是,FileItem 对象的响应方法可以使得我们轻松地获取文件名、文件大小、路径等等;

4、最重要的是,使用 JD-GUI 反编译器简单地看看开源的 fileupload 包中的类组织结构,这更加有意思、有用处,:-D

本文出自 “蚂蚁” 博客,请务必保留此出处http://haolloyin.blog.51cto.com/1177454/368162

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在Servlet中使用开源fileupload包实现文件上传功能 的相关文章

  • 以 RESTful 方式增加资源计数器:PUT 与 POST

    我有一个带有计数器的资源 为了举例 我们将该资源称为profile 计数器是数量views对于该配置文件 Per the 休息维基 http rest blueoxen net cgi bin wiki pl HttpMethods PUT
  • 响应 301 永久移动

    我曾经得到以下对 php 请求的响应 回复
  • HTTP代理服务器

    我开始研究一个用 C 编写的非常基本的 HTTP 代理服务器 Edit 只是转发我的请求的东西 此时我很难理解如何继续 任何帮助都会有益的 看一眼micro proxy http acme com software micro proxy
  • 回形针不支持 .doc 文件

    在 Rails 4 0 2 中 我使用回形针 gem 上传文件 但它不支持 doc 文件 在文件上传字段下方 显示一条错误消息 扩展名与其内容不匹配 在模型中 检查内容类型的验证如下 validates attachment content
  • 有没有办法使用 ASP.NET 在用户离开页面时始终运行某些服务器端代码?

    我想知道当用户离开 ASP NET 中的页面时是否有任何方法可以始终运行一些服务器端代码 页面卸载事件不好 因为如果有人单击链接 则不会调用该事件 理想情况下 即使用户关闭浏览器 我也希望代码能够运行 我怀疑我所问的问题是不可能的 但问一下
  • Access-Control-Allow-Origin值跨站缓存

    我正在尝试编写一个 nginx 配置来处理 http 和 https 上的两个站点 只要客户端从不访问这两个站点 它似乎就可以工作 但如果它们这样做 就会出现缓存 跨站点问题 Allow cross origin location eot
  • C 编程 - 文件 - fwrite

    我有一个关于编程和文件的问题 while current NULL if current gt Id Doctor 0 current current gt next id doc current gt Id Doctor if curre
  • 网站(Google 和/或您)应如何处理 Accept-Language 标头?

    很长一段时间以来 我对谷歌在以下情况下的行为并不满意 并且在无意中注意到之后80 其他人 https stackoverflow com questions 1011167 what are common ui misconceptions
  • 在 C++ 中检查文件是否存在的最佳方法是什么? (跨平台)

    我已阅读以下答案检查 C 中文件是否存在的最佳方法是什么 跨平台 https stackoverflow com questions 230062 whats the best way to check if a file exists i
  • 如何在android中创建nanohttpd服务器?

    其实我也查过一些问题 然后去github上找了一下 但我是新来的 我无法理解这个例子 我想在android中创建http服务器 这样我就可以在PC浏览器中访问它 我有一个类扩展 nanohttpd 的实例 但服务器无法工作 不知道为什么 我
  • 无法使用 Struts 2 重定向 JSP 文件并显示值

    我创建了一个简单的程序 使用文本字段获取用户的名字和姓氏 但问题是 当我单击提交按钮时 我无法将其重定向到另一个显示用户名字和姓氏的 jsp 文件 这是我的HelloAction class package com novamsc trai
  • 将所有文件与指定目录(和子目录)中的所有文件进行二进制比较

    我需要将目录及其子目录中包含的所有文件与同一目录及其子目录中包含的所有其他文件进行比较 并将匹配文件的路径记录到文本文件或 CSV 我意识到有一些软件工具可以做到这一点 但除非它可以在 Windows 中开箱即用 否则我将不被允许在我的网络
  • 我可以用关闭的文件对象做什么?

    当您打开文件时 它存储在一个打开的文件对象中 该对象使您可以访问该文件的各种方法 例如读取或写入 gt gt gt f open file0 gt gt gt f
  • 在 JSP 或 Javascript 中清除浏览器缓存中的图像

    我正在为一所大学开发JSP Web 应用程序 用户页面中显示人员图片 用户注销后如何从网络浏览器缓存中清除这张图片 使用 JSP 或 JavaScript 那是不可能的 最好的选择是完全禁用相关资源的缓存 创建一个filter https
  • linux下如何从文本文件中获取值

    我有一些文本格式的文件 xxx conf 我在这个文件中有一些文本 disablelog 1 当我使用 grep r disablelog oscam conf 输出是 disablelog 1 但我只需要值1 请问你有什么想法吗 一种方法
  • React 文件预览 (FIREBASE)

    我目前将文件存储在 Firebase 存储中 我希望能够实时生成每个文件的文件预览 映射 例如 PDF 文件会将第一页显示为图像 docx 将是文档的第一页 pptx 将是第一张幻灯片 未知文档将是默认文档符号 有人知道有什么好的服务可以轻
  • java.lang.IllegalStateException:提交响应后无法调用 sendRedirect()

    这两天我一直在尝试找出问题所在 我在这里读到我应该在代码中添加一个返回 我做到了 但我仍然得到 java lang IllegalStateException Cannot call sendRedirect after the respo
  • python的shutil.move()在linux上是原子的吗?

    我想知道python的shutil move在linux上是否是原子的 如果源文件和目标文件位于两个不同的分区上 行为是否不同 或者与它们存在于同一分区上时的行为相同吗 我更关心的是如果源文件和目标文件位于同一分区上 shutil move
  • 如何使用 Netty 连接到运行 HTTP 服务器的 UNIX 域套接字?

    我正在尝试使用 Netty 连接到 Docker UNIX 域套接字 到目前为止 这是我的尝试 PostConstruct public void init throws Exception io netty bootstrap Boots
  • 使用 POST 将数据从 Android 发送到 AppEngine Datastore

    抱歉 如果这是一个简单的问题 但我只是不知道我应该做什么 而且我认为我有点超出了我的深度 我想将数据从 Android 应用程序发送到在 Google App Engine 上运行的应用程序 数据必须从那里写入数据存储区 我的数据主要采用对

随机推荐

  • Mixlab工作坊工具箱:talking face

    Talking face 是一种计算机图形学和人工智能的技术 可以实现将一段音频转换为逼真的人脸动画 它可以用于视频游戏 虚拟主持人 语音助手等应用中 使人机交互更加自然和生动 1 SadTalker Video Lip Sync 基于Sa
  • 无涯的技术与成长的迷茫

    记得上大学之前 老师会为我们规划好一切 什么时候要高考 在什么时间点应该掌握哪些技能 每天要学什么 作业是什么 什么时候要放假了 一切都清晰明了 忙碌 但也充实 而上了大学后 感受最深的一点就是迷茫 没有方向 再也没有人为自己规划好一个明确
  • 【Spring从入门到实战】第 6 讲:SpringBoot 的事务管理

    本文已收录于专栏 Spring从入门到实战 专栏前言 大家好 我是执梗 本专栏将从Spring入门开始讲起 详细讲解各类配置的使用以及原因 到使用SpringBoot进行开发实战 旨在记录学习生活的同时也希望能帮到大家 如果对您能有所帮助
  • Google Maven Replacer Plugin插件详解

    在Maven项目的构建过程中 对于Maven标准预定义变量 或者
  • Android Studio App开发入门之图形定制Drawable的讲解及实战(附源码 超详细必看)

    运行有问题或需要源码数据集请点赞关注收藏后评论区留言 图形Drawable Android把所有能够显示的图形都抽象为Drawable类 这里的图形不止是图片 还包括色块 画板 背景等等 包含图片在内的图形文件放在res的目录的各个draw
  • 本地改代码服务器同时修改,sync_web: 将本地的修改通过ftp一键同步到服务器上 ,非常适合维护多个网站并且经常改动代码的情况...

    sync web 将本地的修改通过ftp一键同步到服务器上 非常适合维护多个网站并且经常改动代码的情况 监测文件变动依赖于svn或git author hellstar 在ksc的sync web项目基础上改进 需要安装python2 7环
  • c++11之std::enable_shared_from_this入门

    一 std enable shared from this
  • MySQL之rank() over(order by)

    一 准备工作 创建一个表palyers CREATE TABLE players pid int 2 NOT NULL AUTO INCREMENT name varchar 50 NOT NULL age int 2 NOT NULL P
  • JSON、AJAX简单介绍

    链接 https pan baidu com s 1CS9eQJB YyXorHR7k4P Ww 提取码 nkt2 JSON JavaScript 对象表示法 JavaScript Object Notation JSON 是存储和交换文本
  • 偷偷爆料下国内比较大型的 IT 软件外包公司名单(2023 最新版!)

    点击关注公众号 Java干货及时送达 来源 网络 1 软件外包公司名单 2 如何区分是否是外包公司 3 外包公司真是无一是处吗 4 软件外包的几种形式 5 哪些情况可选择外包 根据网上的资料 整理出来的一份国内软件外包公司的名单 找工作的同
  • RS485收发切换多0x00数据影响bootload升级程序

    串口升级使用RS485接口 RS485收发切换多0x00数据 部分有问题电路板在app程序中输入调试指令有响应 app通过ULINK下载 而使用ymodem在bootloader中升级程序失败 通过printf打印捕捉到数据包头多0x00数
  • 【机器学习】支持向量机SVM - 对SVM与核函数的理解及sklearn参数详解

    支持向量机是在深度学习流行开来之前 性能表现最好的一种机器学习方法 在看这篇blog之前 默认读者已经有了对支持向量机的基本概念的认识 一 支持向量机的进一步理解 支持向量机的优化目标在逻辑回归优化目标基础上进一步产生的 具体优化目标不说了
  • web标准化设计:常用的CSS命名规则

    头 header 内容 content container 尾 footer 导航 nav 侧栏 sidebar 栏目 column 页面外围控制整体布局宽度 wrapper 左右中 left right center 登录条 loginb
  • (二) three.js 导入模块

    导入模块 目录结构 示例 First html 导入three js 的模块 script 标签导入模块 红色框是导入three js 下面绿色框就不用加type module Import导入模块 同样注意红色框和绿色框的对应关系
  • es6面试题

    1 es5和es6的区别 说一下你所知道的es6 ECMAScript5 即ES5 是ECMAScript的第五次修订 于2009年完成标准化ECMAScript6 即ES6 是ECMAScript的第六次修订 于2015年完成 也称ES2
  • 常见的通讯协议总结(USART、IIC、SPI、485、CAN)

    目录 一 通讯的基本概念 1 串行通讯 2 并行通讯 3 串行通讯与并行通讯对比 4 传输模式 单工 半双工 全双工 二 USART 串口通讯 1 物理层 2 协议层 1 波特率 2 起始和停止信号 3 有效数据 4 数据校验 2 异步串行
  • 使用CSMA/CD协议一个计算题

    题干 首先计算一下A这个以太网所容许的最短的帧它的发送帧的长度时间为 8 前同步码为8 64 最短帧长 8 单位转换b到B 576比特 有关于单位转换 B是Byte的缩写 B就是Byte 也就是字节 Byte b是bit的缩写 b就是bit
  • 理解高内聚低耦合

    低耦合 耦合就是元素与元素之间的连接 感知和依赖量度 这里说的元素即是功能 对象 系统 子系统 模块 例如 现在有方法A和方法B 我们在A元素去调用B元素 当B元素有问题或者不存在的时候 A元素就不能正常的工作 那么就说元素A和元素B耦合
  • 【数据结构】实验六:图论

    文章目录 7 1 邻接矩阵表示法创建无向图 参考代码 代码解析 7 2 邻接表创建无向图 参考代码 代码解析 7 3 图深度优先遍历 参考代码 代码解析 7 4 单源最短路径 参考代码 代码解析 7 5 列出连通集 参考代码 代码解析 7
  • 在Servlet中使用开源fileupload包实现文件上传功能

    当我们在 HTML 表单中选择本地文件之后点击 提交 按钮则会将文件上传到服务器中 此时该 HTTP 请求正文的数据类型就是 multipart form data 型的 而在 Servlet 技术中 该 HTTP 请求会被 Servlet