2014-08-06|2291阅|作者:jun|举报 摘要: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);
-----------------------------------------------------------------------------------------