Filter学习笔记

注意!!Filter 是单例模式的!

要实现filter接口,需要在web.xml中配置.
他会在一组资源(比如说servlet html css等)前面执行.
他可以让请求得到或者没法得到目标.
过滤器有拦截请求的能力

注意:filter往往是对一组资源进行统一的操作。

三个方法
服务器启动时创建filter对象
init():filter对象创建之后马上执行
destory:销毁之前执行(服务器关闭的时候销毁)
doFilter(ServletRequest,ServletResponse,FilterChain:每次过滤的时候都会执行。

注意:
filter接口的dofilter三个参数
filterchain的dofilter只有两个接口,用来放行

web.xml配置

<filter>
		<filter-name></filter-name>
		<filter-class>文件所在路径。</filter-class>
</filter>
<filter-mapping>
		<filter-name></filter-name>
		<url-pattern>(一般都是“/*”)</url-pattern>
		 <!--这里可以写servlet-name。指定特定的servlet,可以有多个、-->
</filter-mapping>

多过滤器

顺序取决于mapping的配置顺序
FilterChain的doFilter方法
          ->执行资源就是执行下一个过滤器, 如果没有下一个过滤器,则目标执行资源
          ->执行顺序示例,astart->bstart->资源->bend->aend

过滤器的四种拦截方式

配置:在 <filter-mapping>中配置 <dispatcher>属性
  1. 拦截请求(不写默认是这个)-> request
  2. 拦截转发 ->forward
  3. 拦截包含 ->include
  4. 拦截错误 ->error ->一般可能会额外设置拦截 <err-page>

应用场景

执行目标资源前做的预处理工作,比如说处理编码。
             request.setCharacterEncoding();
根据条件进行判断,比如说是否登陆。或者禁用ip。
在目标资源执行后,做一些后续处理工作,例如说把目标数据进行处理,或者回程拦截。

应用案例摘要

1.分ip统计访问次数

1.数据保存在map中,map保存在application中,方便项目各个地方应用
2.map创建时机,用listener在服务器启动的时候创建,并保存在application
3. filter中获取map
           可以request.getSession.getServletContext
4.通过init()传的config调用getServletContext,新建一个成员变量,保存起来, 补充:获取ip ->getremoter()

2.粗粒度权限控制

游客,会员,管理员->简单管理权限控制,叫粗粒度,
filter中的参数是servletrequest,先要强转成httpservletrequest
管理员和会员分别存一个session判断登录用户的时候分别判断进行过滤。

3.全站字符乱码问题。

1.注意,要包含get和post两种乱码问题 2.request.setcharacterencoding(“utf-8”)->post 请求编码
3.使用装饰类增强request的getparameter方法->get请求编码
          encodingre继承httpservletwrapper,重写getparameter方法、重新设置编码格式。
4.filter创建对象调用。
        然后getmethod判断是post还是get然后调用响应的编码代码。

4.页面静态化

什么是页面静态化

首先去数据库访问数据,然后把数据保存在一个html页面上,
二次访问就不用再去获取了,直接显示html。
如果数据会经常更新,那么不适合使用页面静态化。

思路

1.给出一个过滤器,把servlet请求的资源所做的输出保存到一个html文件中,重定向到html文件中
2.再次访问的时候,如果这个html已经存在那么直接重定向。
3.怎么输出到html文件中
            掉包response,重写getwriter方法。,在构造方法地方,加一个路径参数,指定html路径
            构造方法中创建一个printwriter,参数是path和编码,这样jsp就会用这个流输出数据。都输出到html中了
            html乱码解决,在show.jsp增加响应头,Context-Type

代码演示
String category = request.getParameter("category");
String htmlPage = category + ".html";//得到对应的文件名称
String htmlPath = config.getServletContext().getRealPath("/htmls");
//得到文件的存放目录
File destFile = new File(htmlPath, htmlPage);
if(destFile.exists()) {
	res.sendRedirect(req.getContextPath() + "/htmls/" + htmlPage);
	return;
}
//如果文件存在则直接重定向
StaticResponse sr = new StaticResponse(res, destFile.getAbsolutePath());
//不存在,创建一个重写后的respnse,设定向指定文件写入html
chain.doFilter(request, sr);
//放行,即生成了html文件
res.sendRedirect(req.getContextPath() + "/htmls/" + htmlPage);
				
				
public class StaticResponse extends HttpServletResponseWrapper {
	private PrintWriter pw;
	public StaticResponse(HttpServletResponse response, String path) 
							throws FileNotFoundException, UnsupportedEncodingException {
		super(response);
		pw = new PrintWriter(path, "utf-8");
	}
				
	public PrintWriter getWriter() {
		return pw;
	}
}

猜你喜欢

转载自blog.csdn.net/digimon100/article/details/86552057