全站压缩---(装饰模式过滤器的应用)
Posted 夏小弥
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了全站压缩---(装饰模式过滤器的应用)相关的知识,希望对你有一定的参考价值。
本例子在过滤器中使用到了装饰模式对response对象进行加强,将加强后的对象传到servlet进行操作将数据写到内存流中(调用的方法在response的加强中已经写好了,使其能够写到内存流中),之后从servlet返回到过滤器再拿到内存流中的数据对前台页面进行输出。
本例中在servlet中会调用到的输出流都已经在过滤器中会调用到的另外的类中进行过了改造了的。
下面是代码:
主页:index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>过滤器应用示例---全站压缩</title>
</head>
<body>
<h2>过滤器应用示例---全站压缩</h2>
<a href="<c:url value='/servlet/FirstServlet'/>">请求第一个servlet--网页压缩输出的基本原理</a><br/>
<a href="<c:url value='/servlet/SecondServlet'/>">请求第二个servlet--网页压缩输出的基本原理</a>
</body>
</html>
过滤器和包装类:
package cn.hncu.filter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.zip.GZIPOutputStream;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
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 resp = new MyResponse((HttpServletResponse)response);
//用增强版的resp放行到servlet中去用(让后台把数据 写到 baout中 )
chain.doFilter(request, resp);//放行--让后台去写
//从增强版的resp的baout中(存放的是源字节数据),把数据取出来进行压缩,
//然后再压缩后的数据用原生的response输出到客户端
ByteArrayOutputStream baout = resp.getBaout();
byte srcBytes[] = baout.toByteArray();//源字节数据
System.out.println(new String(srcBytes,"utf-8"));
System.out.println("压缩前大小:"+srcBytes.length);
//把数据srcBytes 压缩到 baout2
ByteArrayOutputStream baout2 = new ByteArrayOutputStream();
GZIPOutputStream gzip = new GZIPOutputStream(baout2);
gzip.write(srcBytes);//把数据压缩到baout2中
gzip.close();
//把baout2中的数据(压缩后) 取出来,用原生response以gzip格式输出到客户端
byte destBytes[] = baout2.toByteArray();
System.out.println("压缩后大小:"+destBytes.length);
//输出之前告诉客户端:我们的数据是gzip格式,然后输出
HttpServletResponse httpResp =(HttpServletResponse) response;
httpResp.setHeader("Content-Encoding", "gzip");
httpResp.setContentLength(destBytes.length);
OutputStream out = httpResp.getOutputStream();
out.write(destBytes);
@Override
public void destroy()
class MyResponse extends HttpServletResponseWrapper
private ByteArrayOutputStream baout;
public MyResponse(HttpServletResponse response)
super(response);
baout = new ByteArrayOutputStream();
@Override
public ServletOutputStream getOutputStream() throws IOException
return new MyOutputStream(baout);
PrintWriter pw = null;
@Override
public PrintWriter getWriter() throws IOException
pw= new PrintWriter(new OutputStreamWriter(baout, "utf-8"),true);
return pw;
public ByteArrayOutputStream getBaout()
if(pw!=null)
pw.close();
return baout;
class MyOutputStream extends ServletOutputStream
private ByteArrayOutputStream baout;
public MyOutputStream(ByteArrayOutputStream baout)
this.baout = baout;
@Override
public void write(int b) throws IOException
baout.write(b);//把数据写到baout中了
两个不同输出类型的servlet
输出字节FirstServlet
package cn.hncu.servlets;
import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class FirstServlet extends HttpServlet
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
doPost(request, response);
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
response.setContentType("text/html;charset=utf-8");
String str="网页压缩数据hncuhdncu网页压缩数据hncuh数据hncuhdncu网页压缩数据hncuh数据hncuhdncu网页压缩数据hncuhdncu网页压缩数据hncuhdncu";
System.out.println("原大小: "+str.getBytes("utf-8").length);
OutputStream out=response.getOutputStream();
out.write(str.getBytes("utf-8"));
//注意,虽然MyEclipse环境设置的是utf-8编码,但本句“str.getBytes()”却是以gbk方式编码---应该是Tomcat中的JVM采用的方式
输出字符SecondServlet
package cn.hncu.servlets;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class SecondServlet extends HttpServlet
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
doPost(request, response);
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
response.setContentType("text/html;charset=utf-8");
String str="网页压缩数据hncuhdncu网页压缩数据hncuh数据hncuhdncu网页压缩数据hncuh数据hncuhdncu网页压缩数据hncuhdncu网页压缩数据hncuhdncu";
System.out.println("原大小: "+str.getBytes("utf-8").length);
PrintWriter out=response.getWriter();
out.write(str);
out.close();
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<filter>
<filter-name>gzip</filter-name>
<filter-class>cn.hncu.filter.GZipFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>gzip</filter-name>
<url-pattern>/servlet/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>FirstServlet</servlet-name>
<servlet-class>cn.hncu.servlets.FirstServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>SecondServlet</servlet-name>
<servlet-class>cn.hncu.servlets.SecondServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FirstServlet</servlet-name>
<url-pattern>/servlet/FirstServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>SecondServlet</servlet-name>
<url-pattern>/servlet/SecondServlet</url-pattern>
</servlet-mapping>
</web-app>
以上是关于全站压缩---(装饰模式过滤器的应用)的主要内容,如果未能解决你的问题,请参考以下文章