一、过滤器是什么?有什么?
1、过滤器属于Servlet规范,从2.3版本就开始有了。
2、过滤器就是对访问的内容进行筛选(拦截)。利用过滤器对请求和响应进行过滤
二、编写步骤和执行过程
1、编码步骤:
a、编写一个类:实现javax.servlet.Filter接口
public class FilterDemo1 implements Filter {
public FilterDemo1(){
System.out.println("调用了默认的构造方法");
}
//用户每次访问被过滤的资源,都会由服务器调用该方法实现过滤
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.out.println("FilterDemo1执行过滤前");
//对请求进行拦截,代码写在这
chain.doFilter(request, response);//放行
//对响应进行拦截,代码写在这
System.out.println("FilterDemo1执行过滤后");
}
public void destroy() {
System.out.println("调用了销毁方法");
}
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("调用初始化方法");
}
}
b、配置web.xml,指定需要过滤的资源。(和Servlet的配置相当类似)
2、过滤器的执行过程(生命周期)
生命周期:
诞生:过滤器的实例是在应用被加载时就完成的实例化,并初始化的。
存活:和应用的生命周期一致的。在内存中是单例的。针对拦截范围内的资源访问,每次访问都会调用void doFIlter(request,response.chain)进行拦截。
死亡:应用被卸载。
三、串联过滤器
一个过滤器接着另外一个过滤器。执行的顺序 按照web.xml的先后顺序
随意 访问 会先直接FilterDemo2 的 再执行 FilterDemo3的
会输出 :
FilterDemo2前
FilterDemo3前
执行内容
FilterDemo3后
FilterDemo2后
四、案例:
1、解决请求参数(POST)和响应输出的乱码过滤器
//解决post方式请求参数和响应编码问题的过滤器
public class SetCharacterEncodingFilter implements Filter {
private FilterConfig filterConfig;
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
String encoding = filterConfig.getInitParameter("encoding");//用户可能忘记了配置该参数
if(encoding==null){
encoding = "UTF-8";//默认编码
}
request.setCharacterEncoding(encoding);//只能解决POST请求参数的中文问题
response.setCharacterEncoding(encoding);//输出流编码
response.setContentType("text/html;charset="+encoding);//输出流编码,通知了客户端应该使用的编码
chain.doFilter(request, response);
}
public void destroy() {
}
}
将 编码类型写在 Filter参数中
2、动态资源不要缓存的过滤器
Servlet/JSP:动态资源不要缓存。
这里 将 Servletrequest 和 ServletResponse 转换为 HttpServlet 的方法 避免发生错误
HttpServletRequest request = null;
HttpServletResponse response = null;
try{
request = (HttpServletRequest)req;
response = (HttpServletResponse)resp;<br>}catch(Exception e){
throw new RuntimeException("not-http request or response");
}
//控制动态资源不要缓存过滤器
public class NoCacheFilter 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; 不使用该方法
HttpServletRequest request = null;
HttpServletResponse response = null;
try{
request = (HttpServletRequest)req;
response = (HttpServletResponse)resp;
}catch(Exception e){
throw new RuntimeException("not-http request or response");
}
response.setHeader("Expires", "-1");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "no-cache");
chain.doFilter(request, response);
}
public void destroy() {
}
}
动态过滤掉 Servlet 和Jsp
3、静态资源控制缓存时间的过滤器
//控制静态资源的缓存时间
public class StaticResourcesNeedCacheFilter implements Filter {
private FilterConfig filterConfig;
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
}
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = null;
HttpServletResponse response = null;
try{
request = (HttpServletRequest)req;
response = (HttpServletResponse)resp;
}catch(Exception e){
throw new RuntimeException("not-http request or response");
}
long time = 0;//缓存的时间
//根据用户请求的uri地址的后缀:/day19_00_filter/1.html
String uri = request.getRequestURI();
String exName = uri.substring(uri.lastIndexOf(".")+1);
if("html".equals(exName)){
String value = filterConfig.getInitParameter("html");//小时
time = Long.parseLong(value)*60*60*1000;
}
if("css".equals(exName)){
String value = filterConfig.getInitParameter("css");//小时
time = Long.parseLong(value)*60*60*1000;
}
if("js".equals(exName)){
String value = filterConfig.getInitParameter("js");//小时
time = Long.parseLong(value)*60*60*1000;
}
response.setDateHeader("Expires", System.currentTimeMillis()+time); //Expires 控制时间
chain.doFilter(request, response);
}
public void destroy() {
}
}
4、//*用户自动登录过滤器:
使用了Md5 加密
Base64编码:很重要