本篇博客知识点
1.理解过滤器
2.如何写过滤器
3.全站压缩实例
理解过滤器
过滤器,顾名思义就是用来过滤的—肯定是放在两个东西之间的,最常见的就是放在浏览器和服务器之间的—-Servlet
只要是客户端请求服务器内的所有网页,Servlet.等。中间都可以设置一个过滤器。
如何写过滤器
1.实现一个过滤器的接口
public class GzipFilter implements Filter{
2.实现它的三个方法—用个做实际功能的
3.在web.xml中配置过滤器参数—用来设置拦截谁的
xml中和Servlet配置一样要配置两个参数
其中第一个:filte,和servlet类似
<filter>
<filter-name>GzipFilter</filter-name>---改过滤器名字
<filter-class>cn.hncu.filters.GzipFilter</filter-class>---改过滤器的类再哪
</filter>
第二个:filter-mapping:- FORWARD
- INCLUDE
- REQUEST
- ASYNC
- ERROR
<filter-mapping>
<filter-name>GzipFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher></dispatcher>
<servlet-name></servlet-name>
</filter-mapping>
url-pattern---拦截的路径/*表示所有
dispatche---拦截以下这个中选 FORWARD、INCLUDE、REQUEST、ERROR、ASYNC 默认是REQUEST
servlet-name---拦截那个Servlet 给名字就好了
配置说明
过虑器的配置:以下几乎是所有单位的标准配置
<filter>
<filter-name>autoLoginFilter</filter-name>
<filter-class>cn.itcast.autologinfilter.AutoLoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>autoLoginFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
filter-name是过虑器的名称
filter-class是过虑器的类文件
init-param是过虑器的初始化参数。
param-name – 是参数名。
param-value - 是参数值。
filter-mapping是过虑器的映射信息。
url-pattern-是需要过虑的资源url.
全站压缩实例
过滤器代码
package cn.hncu.filters;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
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;
/*
* 全战压缩~ 思路:去之前把response加强了(带个容器),回来的时候把容器内的东西压缩了 再用原来response的输出去
*/
public class GzipFilter implements Filter{
@Override
public void init(FilterConfig paramFilterConfig) throws ServletException {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest paramServletRequest,
ServletResponse paramServletResponse, FilterChain paramFilterChain)
throws IOException, ServletException {
HttpServletResponse resp = (HttpServletResponse) paramServletResponse;
MyResponse respone = new MyResponse(resp);
//用我们写的带容器的Myrespone 替换原来的
paramFilterChain.doFilter(paramServletRequest, respone);
//执行完了后,拿到源数据~
byte[] src_data =respone.getBout().toByteArray();
//测试一下源数据长度
System.out.println(src_data.length);
//通过gizp对源数据压缩
ByteArrayOutputStream bout = new ByteArrayOutputStream();
GZIPOutputStream gzip = new GZIPOutputStream(bout);
gzip.write(src_data);
gzip.close();// 关流很重要不然会没数据啊~
byte[] gzip_data = bout.toByteArray();
//测试一下压缩后的数据长度
System.out.println(gzip_data.length);
//压缩完以后,再通过原来的response发送出去
resp.setHeader("Content-Encoding", "gzip");
resp.getOutputStream().write(gzip_data);
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
}
class MyResponse extends HttpServletResponseWrapper{
private ByteArrayOutputStream bout = new ByteArrayOutputStream();
private PrintWriter writer = null;
public MyResponse(HttpServletResponse response) {
super(response);
}
@Override
public ServletOutputStream getOutputStream() throws IOException {
return new MyOutputStream(bout);
}
@Override
public PrintWriter getWriter() throws IOException {
writer= new PrintWriter(new OutputStreamWriter(bout, "utf-8"),true);
return writer;
}
public ByteArrayOutputStream getBout(){
if(writer!=null){ // 这一句很重要,没有这个关流会导致网页很多数据在缓存内,网页无法显示
writer.close();
}
return bout;
}
}
class MyOutputStream extends ServletOutputStream{
private ByteArrayOutputStream bout = null;
public MyOutputStream(ByteArrayOutputStream bout){
this.bout = bout;
}
@Override
public void write(int b) throws IOException {
bout.write(b); //把数据读到容器中区
}
}
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">
<display-name></display-name>
<filter>
<filter-name>GzipFilter</filter-name>
<filter-class>cn.hncu.filters.GzipFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>GzipFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>cn.hncu.servlet.LoginServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>WordServlet</servlet-name>
<servlet-class>cn.hncu.servlet.WordServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>Gzip_Servlet</servlet-name>
<servlet-class>cn.hncu.servlet.Gzip_Servlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/LoginServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>WordServlet</servlet-name>
<url-pattern>/WordServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Gzip_Servlet</servlet-name>
<url-pattern>/Gzip_Servlet</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
说明一下:因为真个网址会有两种流,字节流和字符流,我们要做到全站压缩就得兼容两种。其中有一些细节我已经写在代码注释里了