全站压缩(filter)
---------------------------------------------------------------------------------------------------------------------------
为什么要进行数据压缩?
为了节省 访问网站时的流量,程序开发人员,在开发程序时,应该在服务器端,植入 数据压缩技术。
比如:用户在客户端 用手机(gprs)访问一个网站,如果此网站没有使用 数据压缩技术,那么用户
在此网站上,使用的 流量 可想而知。
----------------------------------------------------------------------------------------------------------------------------
数据压缩:在用户请求数据时,显示的结果经过一个压缩包传递的。
在java中有一个类,专门负责压缩数据
GZIPOutputStream--输出流--压缩工具流
----------------------------------------------------------------------------------------------------------------------------
应该对哪些数据进行压缩?
只对字符进行压缩
因为对电影和图片等进行压缩,消耗内存很大。
没有任何意义。
-----------------------------------------------------------------------------------------------------------------------------
**Gzip核心代码
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 准备压缩数据
String str = "大家好";
// 将数据封装到byte数组
byte[] beforeDatas = str.getBytes("UTF-8");
// 准备容器,盛放压缩数据
ByteArrayOutputStream container = new ByteArrayOutputStream();
// 创建压缩工具
GZIPOutputStream gzipTool = new GZIPOutputStream(container);
// 执行压缩
gzipTool.write(beforeDatas);
// gzip拥有缓存,需要刷新
gzipTool.close();
// 从container中获取 压缩数据
byte[] afterDatas = container.toByteArray();
//验证压缩比
//System.out.println("before:" + beforeDatas.length);
//System.out.println("after:" + afterDatas.length);
// 获取输出字节流,*注意*只能用 字节流
ServletOutputStream outputStream = response.getOutputStream();
// 设置 响应编码,即输出流、浏览器编译 编码
response.setContentType("text/html;charset=UTF-8");
// 通知浏览器,这是压缩后的数据
response.setHeader("Content-Encoding", "gzip");
outputStream.write(afterDatas);
outputStream.close();
}
--------------------------------------------------------------------------------------------------------------
**全站压缩:
全站:即为整个站点。
在myeclipse中,为一个web_program。
对应到tomcat中,是发布到webapp(WebApplication)中的一个web_program。
tomcat--web服务器,其中webapp中,存放着发布的站点。
一个站点--百度、谷歌、又或者搜狐。
压缩:利用web技术,对 客户端 访问 站点中 的字符信息,服务端 进行压缩--打包后,
再响应给 客户端。
全站压缩:通过filter拦截用户访问的字符信息,使用gzip压缩后,响应给用户。
------------
*全站压缩 分析:
第一步:
在servlet,使用response.getWriter(),正常输出字符。
*只是在这里,我们获得的PrintWriter会是我们自己创建的类。
第二步:
创建MyResponse extends HttpServletResponseWrapper
复写getWriter(),其他方法还用父类的。
第三步:
使用filter,拦截字符。
创建MyResponse,并将其放入doFilter()。
在doFilter()后面,使用压缩技术。
*核心代码:
第一步:
public class OutServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter writer = response.getWriter();
writer.print("早上好!");
writer.close();
}
}
第二步:
public class MyResponse extends HttpServletResponseWrapper{
//声明自己的PrintWriter
private PrintWriter printWriter;
//声明一个container
private ByteArrayOutputStream container;
public MyResponse(HttpServletResponse response) {
super(response);
System.out.println("new MyResponse时 创建container");
container = new ByteArrayOutputStream();
}
//重写getWriter()
@Override
public PrintWriter getWriter() throws IOException {
printWriter = new PrintWriter(new OutputStreamWriter(container, "UTF-8"));
return printWriter;
}
//获取 压缩前 数据
public byte[] getBeforeDatas(){
return container.toByteArray();
}
}
第三步:
public class GzipFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
//把MyResponse传给servlet
MyResponse myResponse = new MyResponse((HttpServletResponse)response);
//将请求放行,传入我们提供的MyResponse,进入到servlet
chain.doFilter(request, myResponse);
//从servlet执行后,通过此filter返回到浏览器
//获取beforeDatas
byte[] beforeDatas = myResponse.getBeforeDatas();
//声明 压缩后 数据存放container
ByteArrayOutputStream container = new ByteArrayOutputStream();
//创建压缩工具
GZIPOutputStream gzipTool = new GZIPOutputStream(container);
//执行压缩
gzipTool.write(beforeDatas);
//刷出缓存
gzipTool.close();
//获得压缩后的数据
byte[] afterDatas = container.toByteArray();
//查看压缩比
System.out.println("before:"+beforeDatas.length);
System.out.println("after:"+afterDatas.length);
//转换响应类型
HttpServletResponse resp = (HttpServletResponse)response;
//设置响应编码
resp.setContentType("text/html;charset=UTF-8");
//通知浏览器,此数据为 压缩后的数据
resp.setHeader("Content-Encoding", "gzip");
//必须使用 字节流 输出
ServletOutputStream outputStream = resp.getOutputStream();
outputStream.write(afterDatas);
outputStream.close();
}
@Override
public void destroy() {
}
}