过滤器的简介和简单应用(禁止缓存,设置中文乱码等)
一 过滤器的简介
1.Filter简介
Seervelt API中提供了一个Filter接口,开发web应用时,如果编写的java类实现了这个接口,则把这个java类称之为过滤器
2.Filter如何拦截的---使用不同的过滤器,拦截不同的请求,形成过滤器链
Filter接口中有一个doFilter方法,当开发人员编写好Filter,并配置对哪个web资源进行拦截后,web服务器每次在调用web资源的servet时,首先都会先调用一下filter的doFilter方法,目的如下:
(1)调用目标资源之前,让一段代码执行
(2)是否调用目标资源
(3)调用目标资源之后,让一段代码执行
二 过滤器的作用
(1)控制请求是否最终能到达目标资源
(2)进行拦截
(3)在chain方法之前的操作,对应答的数据进行的操作
三 Filter的生命周期
public void init(FilterConfig arg0) throws ServletException {
}
public void destroy() {
}
初始化方法调用是在服务器加载的时候调用,销毁的方法是在服务器停掉的时候,而不是在访问时,并且方法都只调用一次。
四 过滤器开发入门
1.过滤器的执行过程:
请求到达服务器,先读取web.xml文件中的配置文件,通过反射的机制,创建一个Filter对象,看是否与自己的过滤条件相同,如果有过滤器,有chain参数,就查找是否还有下一个过滤器,直到查找不到过滤器,再执行目标文件。
2.过滤器的配置
<filter>
<filter-name>filter1</filter-name>
<filter-class>com.hbsi.web.filter.FilterDemo1</filter-class>
</filter>
<!—-拦截的请求--(所有的)-->
<filter-mapping>
<filter-name>filter1</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
注:
决定过滤器顺序的是web.xml中的 <filter-mapping>标签
过滤器不能产生应答
3.Java类中继承Filter接口,并实现其中的doFilter方法
public void doFilter(ServletRequest request, ServletResponseresponse,
FilterChain chain) throws IOException, ServletException {
System.out.println("呵呵");
//让请求到达最终资源
chain.doFilter(request,response);
System.out.println("wwwwwwwwwwww");
}
说明:再建一个jsp页面,当执行index.jsp页面前,工程会调用web.xml配置文件,并把配置文件中的filter封装成对象,初始化参数的封装,执行完init方法之后,去调用doFilter方法,一开始输出“呵呵“,然后遇到了chain调用的方法,这个方法是让请求达到最终资源的,所以会执行目标文件(index.jsp),并输出index.jsp中的内容再用response对象返回并输出doFilter方法中的最后一条输出语句。
五 Fileter常见的应用
1. 统一全站字符编码的过滤器
(1)使用的原因:
如果没有过滤器,在每一个页面中都要写上编码方法,如果把编码方法写到过滤器中,只用写一遍,并且在xml文件中配置初始化参数可以不直接指定编码方法,提高灵活性
(2)代码分析
在java中的代码
public class CharSetEncodingFilter implements Filter {
//过滤器统一解决乱码问题
private FilterConfig filterConfig;
public void destroy() {
// TODO Auto-generatedmethod stub
}
private String defaultCharset = "utf-8";
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException{
//模板代码
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse rep = (HttpServletResponse)response;
//得到初始化参数
String charset =filterConfig.getInitParameter("encode");
if(charset==null){
charset = defaultCharset;
}
//请求对象
request.setCharacterEncoding(charset);
//应答对象---一般情况下不设置,因为过滤器不产生应答
rep.setCharacterEncoding(charset);
rep.setContentType("text/html;charset="+charset);
chain.doFilter(req, rep);
}
public void init(FilterConfig config) throws ServletException {
this.filterConfig=config;
}
}
在xml文件中的配置
<filter>
<filter-name>CharsetEncodeFilter</filter-name>
<filter-class>com.hbsi.web.filter.CharSetEncodingFilter</filter-class>
<init-param>
<param-name>encode</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharsetEncodeFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
测试类的使用
先在jsp页面中建一个<from>表单,并用post方法提交到一个servelet类中并输出即可看到效果
2. 禁止浏览器缓冲页面中的静态资源
(1) java中的代码分析
public class NoCacheFilter implements Filter {
public void destroy() {
}
//浏览器不缓存页面
public void doFilter(ServletRequest request, ServletResponseresponse,
FilterChain chain) throws IOException, ServletException{
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse res = (HttpServletResponse)response;
//设置禁止缓存的消息头
res.setDateHeader("expires", -1);
res.setHeader("Cache-Control", "no-cache");
res.setHeader("Pragma", "no-cache");
chain.doFilter(req, res);
}
public void init(FilterConfig arg0) throws ServletException {
}
}
(2) 在web.xml文件中的配置
<filter-mapping>
<filter-name>NoCacheFilter</filter-name>
<url-pattern>/servlet/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>NoCacheFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
3.设置失效日期
(1) 在java中的代码
public class ExpiresFilters implements Filter {
public void destroy() {
}
// 设置失效日期
public void doFilter(ServletRequest request, ServletResponseresponse,
FilterChain chain) throws IOException, ServletException{
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
// (1)得到请求的资源 是js css jpg???
String uri = req.getRequestURI();
if (uri.endsWith(".css")) {
// 设置页面的失效日期 是从---1970.1.1.0.0.0开始到某个时间点所经历的毫秒数
long expiresTime = Integer.parseInt(filterConfig.getInitParameter("css")) * 1000;
res.setDateHeader("Expires", System.currentTimeMillis()+expiresTime);
} else if (uri.endsWith(".js")) {
long expiresTime = Integer.parseInt(filterConfig.getInitParameter("js")) * 1000;
res.setDateHeader("Expires", System.currentTimeMillis()+expiresTime);
} else if (uri.endsWith(".jsp")) {
long expiresTime = Integer.parseInt(filterConfig.getInitParameter("jsp")) * 1000;
res.setDateHeader("Expires", System.currentTimeMillis()+expiresTime);
}
chain.doFilter(req, res);
}
private FilterConfig filterConfig;
public void init(FilterConfig config) throws ServletException {
this.filterConfig = config;
}
}
(2)在web.xml中的配置
<filter>
<filter-name></filter-name>
<filter-class></filter-class>
<init-param>
<!-- css样式的过期时间 jsp jpg都可以-->
<param-name>css</param-name>
<param-value>120</param-value>
</init-param>
<init-param>
<param-name>jsp</param-name>
<param-value>120</param-value>
</init-param>
<init-param>
<param-name>jpg</param-name>
<param-value>120</param-value>
</init-param>
</filter>