一 过滤器
lFilter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。
l
lFilter接口中有一个doFilter方法,当开发人员编写好Filter,并配置对哪个web资源进行拦截后,WEB服务器每次在调用web资源的service方法之前,都会先调用一下filter的doFilter方法,因此,在该方法内编写代码可达到如下目的:
•
调用目标资源之前,让一段代码执行
•
是否调用目标资源(即是否让用户访问web资源)。
•web服务器在调用doFilter方法时,会传递一个filterChain对象进来,filterChain对象是filter接口中最重要的一个对象,它也提供了一个doFilter方法,开发人员可以根据需求决定是否调用此方法,调用该方法,则web服务器就会调用web资源的service方法,即web资源就会被访问,否则web资源不会被访问。
•
调用目标资源之后,让一段代码执行
IFiter 开发中用到的技术常会用到lDecorator(装饰)设计模式 :
IFiter 开发中用到的技术常会用到lDecorator(装饰)设计模式 :
lDecorator设计模式的实现代码
•
1.首先看需要被增强对象继承了什么接口或父类,编写一个类也去继承这些接口或父类。
•
2.在类中定义一个变量,变量类型即需增强对象的类型。
•
3.在类中定义一个构造函数,接收需增强的对象。
•
4.覆盖需增强的方法,编写增强的代码。
代码片段:主要装饰设计模式对response 的输出流的 文件格式 改为gzip ,代码有难度(仔细分析)
代码片段:主要装饰设计模式对response 的输出流的 文件格式 改为gzip ,代码有难度(仔细分析)
public class GzipFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
}
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)resp;
GzipHttpServletResponse mresponse = new GzipHttpServletResponse(response);
chain.doFilter(request, mresponse);
byte b[] = mresponse.getBufferData();//原始字节:核心问题
System.out.println("压缩前大小:"+b.length);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream gout = new GZIPOutputStream(baos);
gout.write(b);
gout.close();
b = baos.toByteArray();//取出缓存中的数据,已经被压缩过的
System.out.println("压缩后大小:"+b.length);
//告知浏览器压缩方式
response.setHeader("Content-Encoding", "gzip");
response.getOutputStream().write(b);
}
public void destroy() {
}
}
class GzipHttpServletResponse extends HttpServletResponseWrapper{
private ByteArrayOutputStream baos = new ByteArrayOutputStream();
private PrintWriter pw;
public GzipHttpServletResponse(HttpServletResponse response){
super(response);
}
//把数据写到一个缓存中
public ServletOutputStream getOutputStream() throws IOException {
ServletOutputStream sos = super.getOutputStream();
MyServletOutputStream msos = new MyServletOutputStream(sos,baos);
return msos;
}
//转成字节流;把输出的数据搞到baos中
public PrintWriter getWriter() throws IOException {
pw = new PrintWriter(new OutputStreamWriter(baos, super.getCharacterEncoding()));
return pw;
}
public byte[] getBufferData(){
try {
if(pw!=null)
pw.close();
baos.flush();
} catch (IOException e) {
e.printStackTrace();
}
return baos.toByteArray();
}
}
class MyServletOutputStream extends ServletOutputStream{
private ByteArrayOutputStream baos;
private ServletOutputStream sos;
public MyServletOutputStream(ServletOutputStream sos,ByteArrayOutputStream baos){
this.sos = sos;
this.baos = baos;
}
public void write(int b) throws IOException {
baos.write(b);
}
}