JavaWeb之文件上传、下载
时间:2016-12-17 18:07
——文件上传概述
上传不能使用BaseServlet
1、文件上传的作用
例如网络硬盘,就是用来上传和下载文件的。
2、文件上传对表单的限制
1)必须使用表单,而不能是超链接
2)表单的method必须是POST,而不能是GET
3)表单的enctype必须是multipart/form-data
4)在表单中添加type="file",即<input type="file" name="" />
<form action="xxx" method="post" enctype="multipart/form-data">
用户名:<input type="text" name="username" /><br/>
照 片:<input type="file" name="photo" /><br/>
<input type="submit" value="上传" />
</form>
3、文件上传对Servlet的限制
1)当表单为enctype="multipart/form-data"时,不能使用request.getParameter()方法,该方法永远返回null。
2)使用ServletInputStream request.getInputStream()来获取完整的请求体。
4、多部件表单结构
1)分割出多个部件,即一个表单项生成一个部件。
2)一个部件中会自己包含请求头和空行以及请求体。
3)普通表单项:
> 一个头:
* Content-Disposition,包含name="xxx",即表单项名称。
> 体就是表单项的值。
4)文件表单项:
> 两个头:
* Content-Disposition,包含name="xxx",即表单项名称,还有一个filename="xxx",表示上传文件的名称。
* Content-Type:它是上传文件的MIME类型,例如:image/jpeg,表示上传的是图片。
> 体就是上传文件的内容。
——commons-fileupload
* commins-fileupload.jar
* 依赖包:commons-io.jar
这个组件会解析request中的上传数据,解析后的结果是一个表单项数据封装到一个FileItem对象中,只需要调用FIleItem对象的方法即可。(多个表单项会封装多个FileItem,即List<FileItem>)
1、上传三个步骤
相关类:
* 工厂类:DiskFileItemFactory
* 解析器:ServletFileUpload
* 表单项:FileItem(该类对应一个表单项)
1)创建工厂:
DiskFileItemFactory factory = new DiskFileItemFactory();
2)创建解析器:
ServletFileUpload sfu = new ServletFileUpload(factory);
3)使用解析器来解析request,得到FileItem集合:
List<FileItem> fileItemList = sfu.parseRequest(request);
2、FileItem类
普通表单项相关方法:
* boolean isFormField()
是否为普通表单项。
true为普通表单项。
false为文件表单项。
* String getFieldName()
返回当前表单项的名称。
* String getString(String charset)
通过指定编码获取表单项的值。
该方法不适用于文件表单项。
必须指定编码。
文件表单项相关方法:
* String getName()
返回上传的文件名称。
* long getSize()
返回上传文件的字节数。
* String getContentType()
获取MIME类型。
* InputStream getInputStream()
返回上传文件对应的输入流。
* void write(File file)
将上传的文件写入指定文件中。
如果file已存在,则会替换目标文件,如果file不存在,则会创建该文件。
——文件上传简单示例
===============================================================================
com.wyc.servlet.UploadServlet
System.out.println("文件大小:" + size);
------------------------------------------------------------------------------------------------------------------------------
form.jsp
===============================================================================
——文件上传细节
1、把上传的文件放到WEB-INF目录下
如果没有把用户上传的文件放到WEB-INF目录下,那么用户就可以通过浏览器直接访问上传的文件,这是非常危险的。
假如说用户上传了一个JSP文件,然后用户再通过浏览器去访问这个JSP文件,那么服务器就会执行JSP文件中的内容,如果在JSP文件中有如下语句:Runtime.getRuntime().exec("shutdown -s -t 1");.........
通常我们会在WEB-INF目录下创建一个upload目录来存放上传的文件,而在Servlet中找到这个目录需要使用ServletContext()的getRealPath(String)方法,例如在项目中有如下语句:
ServletContext servletContext = this.getServletContext();
String uploadPath = servletContext.getRealPath("/WEB-INF/uploads");
其中uploadPath为:G:\tomcat\webapps\FileDemo\WEB-INF\uploads
2、文件名称(完整路径)
上传的文件名称可能是完整路径。
IE6获取的上传文件名称是完整路径,而在其他浏览器获取的上传文件名称只是文件名称而已,浏览器差异的问题还需要处理一下。
例如:C:\file\哈哈.jpg
可以通过分割字符串来获取文件名。
int index = fileName.lastIndexOf("\\");
if(index != -1)
fileName = fileName.substring(index+1);
3、处理文件名称乱码和普通表单项乱码
当上传的文件名称中包含中文时,需要设置编码,commons-fileupload组件为我们提供了两种设置编码的方式:
request.setCharacterEncoding("utf-8");
fileUpload.setHeaderEncoding(String charset); // 这种方式的优先级高于前一种。
commons-fileupload内部会调用request.getCharacterEncoding();来指定编码。
上传文件的文件内容中包含中文:
通常我们不需要关心上传文件的内容,因为我们会把上传文件保存到硬盘上,也就是说,原文件是什么样子,保存到服务器之后还是什么样子。
如果想要在控制台显示上传文件的内容,那么可以使用fileItem.getString(String encoding)来使用指定编码处理字符串。
文本内容和普通表单项内容都是用FileItem类的getString(String encoding)来处理编码。
4、文件重名问题
应该为每个文件名添加前缀名称,这个前缀要保证不能重复,可以使用UUID。
fileName = CommonUtils.getUuid() + "_" + fileName;
===============================================================================
5、一个目录不能存放过多文件(存放目录打散)
一个目录下不应该存放过多的文件,一般一个目录存放1000个文件就是上限了,如果再多,那么打开目录时就会很“卡”。
也就是说,我们需要把上传的文件存放到不同的目录中,但是也不能为每个上传的文件都新建一个目录,这样会导致目录过多,所以我们应该采用某种算法来“打散”存放文件的目录。
方法有很多,例如使用日期来打散,每天生成一个目录,也可以使用文件名的首字母来生成目录,相同首字母的文件放到同一目录下。
日期打散算法:如果某一天上传的文件过多,那么也会出现一个目录文件过多的情况。
首字母打散算法:
例如abc.txt,那么可以把文件保存到a目录下,如果a目录不存在,则创建a目录。
如果文件名是中文的,因为中文过多,所以会导致目录过多的情况。
哈希打散算法:
* 通过文件名称得到一个int值,即调用hashCode()获取哈希值。
* 将int值转换成16进制。
* 获取16进制的前两位用来生成目录,目录为两层:例如1B2C3D4E5F,使用/1/B/ 来保存文件。
该存储方式非常不直观,一般会将文件存放的目录保存起来,以后访问下载时可以直接获取。
===============================================================================
6、上传的单个文件、整个表单的大小限制
限制上传文件的大小很简单,ServletFileUpload类的setFileSizeMax(long)就可以实现了,参数就是上传文件的上限字节数,例如:servletFileUpload.setFileSizeMax(1024 * 10),表示上限为10kb。
该方法一定要在parseRequest()方法之前调用。
一旦上传的文件大小超出了上限,那么就会在执行parseRequest()方法时抛出FileUploadBase.FileSizeLimitExceededException异常。
我们可以在Servlet中获取这个异常,然后想页面输出“上传的文件大小超出限制”。
限制整个表单的大小:
fileUpload.setSizeMax(long size);
该方法必须在parseRequest()方法之前调用。
如果大小超出限制,会抛出FileUploadBase.SizeLimitExceededException异常。
===============================================================================
7、设置缓存大小与临时目录
* 缓存大小:
默认为10kb,当上传文件超出缓存大小时,先将文件保存到硬盘,当文件上传完毕后,再将文件保存。
* 临时目录:
缓存的保存目录。
* 可以通过DiskFileItemFactory的构造方法来指定缓存大小和临时目录
DiskFileItemFactory(int sizeThreshold, File repository)
> 默认的临时目录为:System.getProperty("java.io.tmpdir");,打印后:G:\apache-tomcat-7.0.72\temp
> 例如:new DiskFileItemFactory(1024 * 10, new File("F:/temp"));
// 打印默认临时目录
===============================================================================
——文件下载
被下载的资源必须放到WEB-INF目录下,然后通过Servlet完成下载。
在JSP页面中给出超链接,链接到DownloadServlet,并提供要下载的文件名称,然后在DownloadServlet获取文件的真实路径,然后把文件写入到response.getOutputStream()流中。
1、概述
下载就是向客户端响应字节数据。
之前响应的都是HTML的字符数据。
其实就是把一个文件编程字节数组,使用response.getOutputStream()来将文件响应给浏览器。
2、下载的要求
两个头、一个流
* Content-Type:表示传递给客户端文件的MIME类型。
> 通过文件名称调用ServletContext的getMimeType()方法得到MIME类型。
* Content-Disposition:
> 它的默认值为inline,表示在浏览器窗口中打开(当打不开时会弹框)。
> attachment;filename=xxx:表示类型为附件,并在弹框的界面中显示下载的文件名。
* 流:要下载的文件数据。
> 自己new 一个输入流即可,然后通过IOUtils完成流的数据写入。
——下载示例
——DownloadUtils(下载文件名乱码问题)
显示在下载框中包含中文名称时,会出现乱码。
* FireFox,使用Base64编码。
* 其他大部分浏览器,使用URL编码。
通用方法:filename = new String(filename.getBytes("gbk"), "iso-8859-1");
浏览器能读懂ISO-8859-1编码
public static String fileNameEncoding(String fileName, HttpServletRequest request) throws Exception{
注意:
Base64Encoder并不属于JDK标准库范畴,但是又包含在了JDK中,解决方法:
1、按照如下方法设置Eclipse导入%JAVA_HOME%\jre\lib目录下的rt.jar包即可,Project->Properties,选择Java Build Path设置项,再选择Libraries标签,Add External Jars添加%JAVA_HOME%\jre\lib\rt.jar就可以使用了。
2、MyEclipse —— Preferences —— Java —— Compiler —— Errors/Warnings —— Deprecated and restricted API —— Forbidden reference(access rules): Ignore
——BASE64Encoder、BASE64Decoder
JavaWeb之文件上传、下载的更多相关文章
- JavaWeb实现文件上传下载功能实例解析
转:http://www.cnblogs.com/xdp-gacl/p/4200090.html JavaWeb实现文件上传下载功能实例解析 在Web应用系统开发中,文件上传和下载功能是非常常用的功能 ...
- JavaWeb实现文件上传下载功能实例解析 (好用)
转: JavaWeb实现文件上传下载功能实例解析 转:http://www.cnblogs.com/xdp-gacl/p/4200090.html JavaWeb实现文件上传下载功能实例解析 在Web ...
- Javaweb学习笔记——上传下载文件
一.前言 在Javaweb中,上传下载是经常用到的功能,对于文件上传,浏览器在上传的过程中是以流的过程将文件传给服务器,一般都是使用commons-fileupload这个包实现上传功能,因为comm ...
- JavaWeb 文件 上传 下载
文件上传下载对于一个网站来说,重要性不言而喻.今天来分享一个JavaWeb方式实现的文件上传下载的小例子. 项目依赖 项目目录 工作流程 文件上传 表单处的设置 服务器端 上传功能的实现 upload ...
- JavaWeb多文件上传及zip打包下载
项目中经常会使用到文件上传及下载的功能.本篇文章总结场景在JavaWeb环境下,多文件上传及批量打包下载功能,包括前台及后台部分. 首先明确一点: 无法通过页面的无刷新ajax请求,直接发下载.上 ...
- JavaWeb:实现文件上传与下载
JavaWeb:实现文件上传与下载 文件上传前端处理 本模块使用到的前端Ajax库为Axio,其地址为GitHub官网. 关于文件上传 上传文件就是把客户端的文件发送给服务器端. 在常见情况(不包含文 ...
- JavaWeb 文件上传下载
1. 文件上传下载概述 1.1. 什么是文件上传下载 所谓文件上传下载就是将本地文件上传到服务器端,从服务器端下载文件到本地的过程.例如目前网站需要上传头像.上传下载图片或网盘等功能都是利用文件上传下 ...
- JavaWeb -- 文件上传下载示例
1. 上传简单示例 Jsp <%@ page language="java" import="java.util.*" pageEncoding=&quo ...
- 转载:JavaWeb 文件上传下载
转自:https://www.cnblogs.com/aaron911/p/7797877.html 1. 文件上传下载概述 1.1. 什么是文件上传下载 所谓文件上传下载就是将本地文件上传到服务器端 ...
- JavaWeb:实现文件上传
JavaWeb:实现文件上传 理解文件上传: 1.上传文件就是把客户端的文件发送给服务器端. 2.HTTP响应的正文部分最常见的是HTML文档,但是也可以是其他任意格式的数据,如图片和声音文件中的数据 ...
随机推荐
- Spark—local模式环境搭建
Spark--local模式环境搭建 一.Spark运行模式介绍 1.本地模式(loca模式):spark单机运行,一般用户测试和开发使用 2.Standalone模式:构建一个主从结构(Master ...
- SpringBoot中时间格式化的5种方法!
在我们日常工作中,时间格式化是一件经常遇到的事儿,所以本文我们就来盘点一下 Spring Boot 中时间格式化的几种方法. 时间问题演示 为了方便演示,我写了一个简单 Spring Boot 项 ...
- 数据结构与算法(python版)
ADT抽象数据类型(ADT:Abstract Data Type):ADT是对数据进行处理的一种逻辑描述,并不涉及如何实现这些处理. 同一ADT可以采用不同的数据结构来实现:1.采用程序设计语言的控制 ...
- ASP.NET中<%=%>、<%%>、<%@%>、<%#%>的用法与区别
1.<%= %> 里面放变量名,获取后台的变量值,直接输入变量到页面上,里面放的变量名,未经过encode eg: 后台: seession["ab"]=ab; 前台: ...
- 第十篇 -- Windows 下免费的GIF录制工具
网址:https://blog.csdn.net/u013019701/article/details/80550411 本人用的第二个,亲测好用.
- 模式识别课程大作业 Shopee 商品图像检索
大作业项目简介 在如今的信息科技时代, 带有拍照功能的移动设备如手机.相机等得到了极大的普及和流行, 各种各样的图片和视频可以随时随地获得, 并借助互联网快速传播, 这种趋势使得网络上的数字图片和视频 ...
- Hadoop (8088)未授权访问
cd /vulhub/hadoop/unauthorized-yarn 加速下载环境 sudo vim /etc/docker/daemon.json 添加 {"registry-mirro ...
- vulnhub-XXE靶机
仅供个人娱乐 靶机信息 靶机下载地址:https://download.vulnhub.com/xxe/XXE.zip 一.主机探测 二.端口服务识别 nmap -sV 192.168.181.149 ...
- 外网远程顶级域名连接群晖的WebDAV文件服务映射盘符
外网远程顶级域名连接群晖的WebDAV文件服务映射盘符 https://www.cnblogs.com/delphixx/p/11846546.html 电子文件管理规范 1.手机拍照截屏 ...
- 用QT写的简单Todo记事本-附源码(浮动窗口)
去年边学边写了搞了很久, 已经好久没继续开发了, 先放出来供大家参考吧. 发现自己的学习能力还是不错的. 技术点: 使用QT, QML技术 代码参考: https://github.com/cnscu ...