Web基础了解版12-上传下载
上传
两个步骤:
用户在页面中选择要上传的文件,然后将请求提交到Servlet
Servlet收到请求,解析用户上传的文件,然后将文件存储到服务器
上传文件表单
<form action="Servlet" method="post" enctype="multipart/form-data">
<input type="file" name="file" /><br /><br />
<input type="submit" value="上传" />
</form>
注意:
表单的method属性必须为post
表单的enctype属性必须为multipart/form-data
上传文件的控件是intput,type属性为file
注意:Servelet
- 当enctype="multipart/form-data" 时,再使用getParamter()获取到内容永远为空。
- 需要引入解析请求中的参数和文件,这个工具就是commons-fileupload。
commons-fileupload
它的作用就是可以从request对象中解析出,用户发送的请求参数和上传文件的流。
commons-fileupload包依赖commons-io,两个包需要同时导入。
核心类:
DiskFileItemFactory
工厂类,用于创建ServletFileUpload,设置缓存等
该类一般直接使用构造器直接创建实例
方法:
public void setSizeThreshold(int sizeThreshold):用于设置缓存文件的大小(默认值10kb)
public void setRepository(File repository):用于设置缓存文件位置(默认系统缓存目录)
ServletFileUpload
该类用于解析request对象从而获取用户发送的请求参数(包括普通参数和文件参数)
该类需要调用有参构造器创建实例,构造器中需要一个DiskFileItemFactory作为参数
方法:
public List<FileItem> parseRequest(HttpServletRequest request):解析request对象,获取请求参数,返回的是一个List,List中保存的是一个FileItem对象,一个对象代表一个请求参数。
public void setFileSizeMax(long fileSizeMax):设置单个文件的大小限制,单位为B。如果上传文件超出限制,会在parseRequest()抛出异常FileSizeLimitExceededException。
public void setSizeMax(long sizeMax):限制请求内容的总大小,单位为B。如果上传文件超出限制,会在parseRequest()抛出异常SizeLimitExceededException。
FileItem
该类用于封装用户发送的参数和文件,也就是用户发送来的信息将会被封装成一个FileItem对象,我们通过该对象获取请求参数或上传文件的信息。
该类不用我们手动创建,由ServletFileItem解析request后返回。
方法:
String getFieldName():获取表单项的名字,也就是input当中的name属性的值。
String getName():获取上传的文件名,普通的请求参数为null。
String getString(String encoding):获取内容,encoding参数需要指定一个字符集。
① 若为文件,将文件的流转换为字符串。
② 若为请求参数,则获取请求参数的value。
boolean isFormField():判断当前的FileItem封装的是普通请求参数,还是一个文件。
① 如果为普通参数返回:true
② 如果为文件参数返回:false
String getContentType():获取上传文件的MIME类型
long getSize():获取内容的大小
write():将文件上传到服务器
//创建工厂类
DiskFileItemFactory factory = new DiskFileItemFactory();
//创建请求解析器
ServletFileUpload fileUpload = new ServletFileUpload(factory);
//设置上传单个文件的的大小
fileUpload.setFileSizeMax(1024*1024*3);
//设置上传总文件的大小
fileUpload.setSizeMax(1024*1024*3*10);
//设置响应内容的编码
response.setContentType("text/html;charset=utf-8");
try {
//解析请求信息,获取FileItem的集合
List<FileItem> items = fileUpload.parseRequest(request);
//遍历集合
for (FileItem fileItem : items) {
//如果是普通的表单项
if(fileItem.isFormField()){
//获取参数名
String fieldName = fileItem.getFieldName();
//获取参数值
String value = fileItem.getString("utf-8");
System.out.println(fieldName+" = "+value);
//如果是文件表单项
}else{
//获取文件名
String fileName = fileItem.getName();
//获取上传路径
String realPath = getServletContext().getRealPath("/WEB-INF/upload");
//检查upload文件夹是否存在,如果不存在则创建
File f = new File(realPath);
if(!f.exists()){
f.mkdir();
};
//为避免重名生成一个uuid作为文件名的前缀
String prefix = UUID.randomUUID().toString().replace("-", "");
//将文件写入到服务器中
fileItem.write(new File(realPath+"/"+prefix+"_"+fileName));
//清除文件缓存
fileItem.delete();
}
}
} catch (Exception e) {
if(e instanceof SizeLimitExceededException){
//文件总大小超出限制
response.getWriter().print("上传文件的总大小不能超过30M");
}else if(e instanceof FileSizeLimitExceededException){
//单个文件大小超出限制
response.getWriter().print("上传单个文件的大小不能超过3M");
}
}
response.getWriter().print("上传成功");
下载
下载文件的关键点:
服务器以一个流的形式将文件发送给浏览器。
发送流的同时还需要设置几个响应头,来告诉浏览器下载的信息。
具体响应头如下:
Content-Type
下载文件的MIME类型
可以通过servletContext. getMimeType(String file)获取
也可以直接手动指定
使用response.setContentType(String type);
响应头样式:Content-Type: audio/mpeg
Content-Disposition
下载文件的名字,主要作用是提供一个默认的用户名
通过response.setHeader("Content-Disposition", disposition)设置
响应头样式:Content-Disposition: attachment; filename=xxx.mp3
Content-Length
下载文件的长度,用于设置文件的长处(不必须)
通过response. setContentLength(int len)设置。
设置后样式:Content-Length: 3140995
接下来需要以输入流的形式读入硬盘上的文件
FileInputStream is = new FileInputStream(file);
这个流就是我们一会要发送给浏览器的内容
通过response获取一个输出流,并将文件(输入流)通过该流发送给浏览器
获取输出流:ServletOutputStream out = response.getOutputStream();
通过输出流向浏览器发送文件(不要忘了关闭输入流)
步骤演示
以下步骤都是在同一个Servlet的doGet()方法中编写的
1.获取文件的流:
String realPath = getServletContext().getRealPath("/WEB-INF/mp3/中国话.mp3");
//获取文件的File对象
File file = new File(realPath);
//获取文件的输入流
FileInputStream in = new FileInputStream(file);
2.获取头信息:
//获取文件的MIME信息
String contentType = getServletContext().getMimeType(realPath);
//设置下载文件的名字
String filename = "zhongguohua.mp3";
//创建Content-Disposition信息
String disposition = "attachment; filename="+ filename ;
//获取文件长度
long size = file.length();
3.设置头信息
//设置Content-Type
response.setContentType(contentType);
//设置Content-Disposition
response.setHeader("Content-Disposition", disposition);
//设置文件长度
response.setContentLength((int)size);
4.发送文件
//通过response获取输出流,用于向浏览器输出内容
ServletOutputStream out = response.getOutputStream();
//将文件输入流通过输出流输出
byte[] b = new byte[1024];
int len = 0;
while((len=is.read(b))> 0){
out.write(b, 0, len);
}
//最后不要忘记关闭输入流,输出流由Tomcat自己处理,我们不用手动关闭
is.close();
乱码
中文文件名会出现乱码问题。解决此问题的方法很简单,在获取文件名之后为文件名进行编码:
filename = java.net.URLEncoder.encode(filename,"utf-8");
火狐浏览器比较特殊需要特殊处理一下。
1.先要获取客户端信息(通过获取请求头中的User-Agent信息)
String ua = request.getHeader("User-Agent");
2.然后判断浏览器版本,做不同的处理
//判断客户端是否为火狐
if(ua.contains("Firefox")){
//若为火狐使用BASE64编码
filename = "=?utf-8?B?"+new BASE64Encoder().encode(filename.getBytes("utf-8"))+"?=";
}else{
//否则使用UTF-8
filename = URLEncoder.encode(filename,"utf-8");
}
String string = new String("你好.jpg".getBytes("gbk"), "iso8859-1");
Web基础了解版12-上传下载的更多相关文章
- web基础---->Fileupload文件的上传
这里我们介绍文件上传的知识,使用的是apache的Commons FileUpload框架. 文件上传的使用 项目的部分结构如下: 一.使用Commons FileUpload的上传功能,我们需要引入 ...
- Java Web 项目的文件/文件夹上传下载
需求: 支持大文件批量上传(20G)和下载,同时需要保证上传期间用户电脑不出现卡死等体验: 内网百兆网络上传速度为12MB/S 服务器内存占用低 支持文件夹上传,文件夹中的文件数量达到1万个以上,且包 ...
- Robot Framework--13 RFS+AutoItLibrary测试web上传下载
转自:http://blog.csdn.net/tulituqi/article/details/21888059 Selenium2library在我们实际测试web页面的时候基本上已经够用了,不过 ...
- Java Web总结(二)-- 上传和下载
在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接 ...
- JAVA Web 之 struts2文件上传下载演示(二)(转)
JAVA Web 之 struts2文件上传下载演示(二) 一.文件上传演示 详细查看本人的另一篇博客 http://titanseason.iteye.com/blog/1489397 二.文件下载 ...
- JAVA Web 之 struts2文件上传下载演示(一)(转)
JAVA Web 之 struts2文件上传下载演示(一) 一.文件上传演示 1.需要的jar包 大多数的jar包都是struts里面的,大家把jar包直接复制到WebContent/WEB-INF/ ...
- java web 文件上传下载
文件上传下载案例: 首先是此案例工程的目录结构:
- WEB文件上传下载功能
WEB文件上传下载在日常工作中经常用到的功能 这里用到JS库 http://files.cnblogs.com/meilibao/ajaxupload.3.5.js 上传代码段(HTML) <% ...
- 文件上传下载(C#,web,asp.net)
目的:在浏览器页面启动上传下载CS软件,实现文件的批量下载与上传. 技术路线: 开发上传下载客户端CS程序与注册程序,压缩放到服务器端指定位置: 开发服务器端程序用以接收上传请求,压缩放到服务器端: ...
- java web service 上传下载文件
1.新建动态web工程youmeFileServer,新建包com,里面新建类FileProgress package com; import java.io.FileInputStream; imp ...
随机推荐
- PHP 手机短信验证码 laravel 实现流程
https://blog.csdn.net/uknow0904/article/details/80336941 本人在自己博客(Laravel)的注册部分 使用手机号注册,需要发送短信验证码. 使用 ...
- [kuangbin带你飞]专题九 连通图B - Network UVA - 315
判断割点的性质: 如果点y满足 low[y]>=dfn[x] 且不是根节点 或者是根节点,满足上述式子的有两个及其以上. 就是割点 如果是起点,那么至少需要两个子节点满足上述条件,因为它是根节点 ...
- ORACLE内部操作
当执行查询时,ORACLE采用了内部的操作. 下表显示了几种重要的内部操作. ORACLE Clause 内部操作 ORDER BY SORT ORDER BY UNION UNION-ALL MIN ...
- idea乱码问题(全)
中文乱码问题分类: 编码普通中文乱码 properties文件中文乱码 console控制台中文乱码 搜索框中文乱码 svn注释中文乱码 问题截图: 2.properties文件中文乱码 4,.搜索框 ...
- asp.net mvc获取路由参数
学习了mvc有一段时间了,本以为直接可以通过request对象直接获取路由参数呢,后来实验了一下发现想错了,mvc有专门获取路由参数的方式,在不同的地方,获取路由参数的方式也不一样,这里分别说一下,在 ...
- [php] 如何处理好autoload
在有了诸如apc之类的cache之后,php的autoloader成为了需要认真考虑的性能点. 参见: http://stackoverflow.com/questions/4788452/does- ...
- Acegi框架介绍
开发四年只会写业务代码,分布式高并发都不会还做程序员?->>> 概述 对于任何一个完整的应用系 统,完善的认证和授权机制是必不可少的.Acegi Securit ...
- setTimeout第三个参数
在廖雪峰大神的官方网站看nodejs的时候,发现自己对Promise函数不甚了解,于是转去看Promise函数,看到了这段代码: function multiply(input) { return n ...
- Linux 内核类设备
一个类的真正目的是作为一个是该类成员的设备的容器. 一个成员由 struct class_device 来表示: struct class_device { struct kobject kobj; ...
- Java并发编程(您不知道的线程池操作), 最受欢迎的 8 位 Java 大师,Java并发包中的同步队列SynchronousQueue实现原理
Java_并发编程培训 java并发程序设计教程 JUC Exchanger 一.概述 Exchanger 可以在对中对元素进行配对和交换的线程的同步点.每个线程将条目上的某个方法呈现给 exchan ...