用户注册



邮箱:

密码:

用户登录


邮箱:

密码:
记住登录一个月忘记密码?

发表随想


还能输入:200字

jun    -  云代码空间

—— 相信 ,梦

文件上传下载

2014-08-06|2241阅||

摘要:1.Filter案例 2.文件上传 3.文件下载 -----------------------------------------------------


1.Filter案例--压缩响应
问题1:怎样对response增强
使用装饰模式
问题2:对哪些方法进行功能增强?
getOutputStream()
getWriter()
问题3:怎样在Filter中可以拦截响应?
chain.doFilter(request,resposne);
在这个下面就代表是响应回数据。

问题4:自定义缓冲区怎样创建?
应该是一个byte[]数组.
ByteArrayOutputStream--->它的目的地就是一个byte[],这个数组是可变的。

问题5:将数据压缩操作
GZipOutputStream

------------------------------------------
增强resposne
使用装饰模式:  我们创建一个类继承 HttpServletResponseWrapper.

============================================================================
tomcat服务器提供压缩机制:

在tomcat中可以配置  
compressableMimeType  ----用于设置什么时候样的数据要进行压缩  MimeType类型  text/html,text/xml,text/plain
compression  开启压缩   可了值 off on

=====================================================================================================
2.文件上传
文件上传在开发中可以替代将数据存储到数据库操作。

1.浏览器端

get与post方式区别?
1.get方式它提交的数据在浏览器上会显示,post不会.
2.get只能提交1kb以下数据
 post允许提交大数据.
3.get请求它的请求参数是在url路径上.
 post请请参数是在请求正文中.
 
文件上传对浏览器端要求:
1.请求方式必须是 method=post
2.<input type="file" name="f"> 必须有名称
3.需要设置encType="multipart/form-data"
enctype="application/x-www-form-urlencoded"默认值

2.服务器端
得到上传的文件内容

可以通过request获取一个InputStream流,可以读取到请求正文中的信息。

如果客户端设置encType="multipart/form-data",那么在http请头中存在一个boundary这个项,
它是请求正文的分隔符。
如果我们要手动完成文件上传,只需要将请求正文中信息根据boundary进行分隔,就可以得到每一部分信息。
可以通过判断信息中是否包含filename项来判断是否是上传项。我们在自己写算法解析数据就可以得到上传文件内容。
通过输出流将信息写到指定文件中完成文件上传。

---------------------------------------------------------------------
上传文件插件:
1.commons-fileupload   apache(应用最多)
2.smart-upload(基本不用)

commons-fileupload使用
1.创建 DiskFileItemFactory---它用于设置相关的属性
2.创建ServletFileUpload对象  它用于解析request对象,获取每一部分上传项
3.通过遍历每一个上传项,得到相关的信息。FileItem

fileupload快速入门
1.导入jar包
commons-fileupload与commons-io的jar包
2.在servlet中完成文件上传
1.创建一个DiskFileItemFactory
DiskFileItemFactory factory = new DiskFileItemFactory();
2.创建一个ServletFileUpload对象
ServletFileUpload upload = new ServletFileUpload(factory);
3.得到List<FileItem>
List<FileItem> fileItems = upload.parseRequest(request);

4.遍历List<FileItem>
FileItem提供的方法
1.isFormFiled 可以判断是否是上传组件
2.getName()可以得到上传文件的名称
3.getFieldName()得到上传组件的名称
4.getString()得到非上传组件的value值
5.getInputStream()得到指向上传文件的一个输入流.
6.write(File file) 通过FileItem对象调用writer方法可以直接将上传文件进行保存.
7.delete()删除临时文件

------------------------------------------------------------------------------------
1.DiskFileItemFactory
主要作用:
1.设置缓冲区大小
2.设置临时文件保存位置

怎样设置缓冲区大小,设置临时文件保存位置
1. public DiskFileItemFactory(int sizeThreshold, File repository)

2.通过DiskFileItemDisk的方法设置
public void setRepository(File repository)  //设置临时文件保存位置
public void setSizeThreshold(int sizeThreshold) //设置缓冲区大小

---------------------------------------------------------------------------------------------------------
2.ServletFileUpload API
1.得到所有的http请求项
List<FileItem> parseRequest(HttpServletRequest r)
2.判断当前是否是上传操作
isMultipartContent(HttpServletRequest r)  返回值为boolean
注意:当使用了fileupload插件,那么也就是说,想要获取请求参数 ,就不能在使用request获取,必须使用FileItem获取.

3.设置上传文件大小
void setFileSizeMax(long fileSizeMax) 设置单个文件上传大小 
void  setSizeMax(long sizeMax) 设置总文件上传大小 

4.上传文件名称包含中文时的乱码问题
setHeaderEncoding()
--------------------------------------------------------------------------------------------------------------
3.FileItem API
1.isFormFiled 可以判断是否是上传组件
2.getName()可以得到上传文件的名称
3.getFieldName()得到上传组件的名称
4.getString()得到非上传组件的value值
5.getInputStream()得到指向上传文件的一个输入流.
6.write(File file) 通过FileItem对象调用writer方法可以直接将上传文件进行保存.
7.delete()删除临时文件
问题:怎样解决非上传组件信息的乱码问题?
getstring("utf-8");

---------------------------------------
关于文件上传时的乱码问题总结:
1.上传文件名称乱码:  ServletFileUpload.setHeaderEncoding("utf-8");
2.非上传组件的value乱码  FileItem.getString("utf-8");

==============================================================================================
多文件上传表单

function addFile() {


document.getElementById("content").innerHTML += "<div><input type='file' name='f'><input type='button' value='removeFile' onclick='delFile(this)'></div>";
}


function delFile(btn) {
document.getElementById("content").removeChild(btn.parentNode);
}

<div id="content">

</div>

------------------------------------------------------------------------------------------------------------------
上传文件问题:
1.上传文件保存位置问题:
上传文件保存的位置要根据需求来分析:
1.上传文件允许浏览器端访问
保存在当前工程下(除了WEB-INF  META-INF及其子目录下)
2.上传文件不允许浏览器端访问
1.保存在WEB-INF  META-INF及其子目录下
2.其它的服务器端的磁盘目录.

2.上传文件重名问题
给文件起个随机名:
1.根据毫秒值
2.根据UUID获取.

3.关于目录分离问题
一个目录下不应该保存过多文件。
1) 按照上传时间进行目录分离 (周、月 )
2) 按照上传用户进行目录分离 ----- 为每个用户建立单独目录 
3) 按照固定数量进行目录分离 ------ 假设每个目录只能存放3000个文件 ,每当一个目录存满3000个文件后,创建一个新的目录
4)分离算法
按照上传文件名称的hashcode分离.
--------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------
文件下载
文件下载方案:
1.使用超连接完成下载(了解)
<a href='${pageContext.request.contextPath}/upload/1.jpg'>1.jpg</a>
<br>
<a href='${pageContext.request.contextPath}/upload/2.jpg'>2.jpg</a>
<br>
<a href='${pageContext.request.contextPath}/upload/3.wav'>3.wav</a>
<br>
<a href='${pageContext.request.contextPath}/upload/4.txt'>4.txt</a>
<br>
如果资源不能被浏览器直接解析,那么就会下载,如果可以被浏览器直接解析,就在浏览器中打开。

护展:队列(优化了递归)

2.通过服务器端以输出流的方式完成下载.(重点)

浏览器端:
通知服务器下载文件名称是什么
<a href="${pageContext.request.contextPath}/download1?filename=1.wav">1.wav</a>
<br>
<a href="${pageContext.request.contextPath}/download1?filename=1.jpg">1.jpg</a>
<br>
<a href="${pageContext.request.contextPath}/download1?filename=1.txt">1.txt</a>
<br>
服务器端
得到要下载的文件名称
String filename=request.getParameter("filename");
在指下的目录下查找这个文件是否存在,如果存在,使用输入流将文件内容读取到,
在通过resposne获取输出流,写回到浏览器端.

注意:在下载时需要指定两项
1.下载文件的mimeType类型
ServletContext.getMimeType(String filename);

String mimeType = this.getServletContext().getMimeType(filename);//得到要下载的文件mimeType类型
2.指定响应头 Content-Disposition
这是一个http响应头

response.setHeader("Content-Disposition","attachement;filename="+filename);

问题:关于下载乱码问题

1.下载时传递的文件名称乱码
提交时,超连接件以get方式提交,在服务器端获取数据会出现乱码.

2.下载时文件名称乱码问题

对于ie浏览器,它需要以utf-8码下载.
对于firefox浏览器,它需要以base64编码下载.
String downloadfilename = "";
String agent = request.getHeader("User-Agent"); // 它用于判断是什么浏览器
if (agent.contains("MSIE")) {
// IE浏览器
downloadfilename = URLEncoder.encode(filename, "utf-8");


} else if (agent.contains("Firefox")) {
// 火狐浏览器
BASE64Encoder base64Encoder = new BASE64Encoder();
downloadfilename = "=?utf-8?B?"
+ base64Encoder.encode(filename.getBytes("utf-8")) + "?=";
} else if (agent.contains("Chrome")) {
// google浏览器
downloadfilename = URLEncoder.encode(filename, "utf-8");
} else {
// 其它浏览器
downloadfilename = URLEncoder.encode(filename, "utf-8");
}


response.setHeader("Content-Disposition", "attachement;filename="
+ downloadfilename);

-----------------------------------------------------------------------------------------
顶 1踩 0收藏
文章评论
    发表评论

    个人资料

    • 昵称: jun
    • 等级: 资深程序员
    • 积分: 1523
    • 代码: 94 个
    • 文章: 24 篇
    • 随想: 0 条
    • 访问: 7 次
    • 关注

    最新提问

      站长推荐