Javaweb中的过滤器可以拦截所有访问web资源的请求或响应操作。
Filter快速入门
步骤:
- 创建一个类实现Filter接口
- 重写接口中方法 doFilter方法是真正过滤的。
- 在web.xml文件中配置
注意:在Filter的doFilter方法内如果没有执行chain.doFilter(request,response)
那么资源是不会被访问到的。
1、创建一个类实现Filter接口
package com.yanglin.filter;
import javax.servlet.*;
import java.io.IOException;
public class Myfilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("在启动服务器的时候就创建");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("拦截");
//放行,执行完相应的操作之后会返回来的
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("返回");
}
@Override
public void destroy() {
System.out.println("销毁");
}
}
2、在web.xml文件中配置
<!--配置拦截-->
<filter>
<filter-name>Myfilter</filter-name>
<filter-class>com.yanglin.filter.Myfilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Myfilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
FilterChain
FilterChain 是 servlet 容器为开发人员提供的对象,它提供了对某一资源的已过滤请求调用链的视图。过滤器使用 FilterChain 调用链中的下一个过滤器,如果调用的过滤器是链中的最后一个过滤器,则调用链末尾的资源。
怎样可以形成一个Filter链?
只要多个Filter对同一个资源进行拦截就可以形成Filter链
怎样确定Filter的执行顺序?
由的先后顺序来确定
如下先执行MyFilter2,在再执行MyFilter
<filter-mapping>
<filter-name>MyFilter2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping> -->
<filter-mapping>
<filter-name>MyFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Filter生命周期:
Filter生命周期与servlet什么周期很像都是:实例化 –> 初始化 –> 服务 –> 销毁
- 当服务器启动,会创建Filter对象,并调用init方法,只调用一次.
- 当访问资源时,路径与Filter的拦截路径匹配,会执行Filter中的doFilter方法,这个方法是真正拦截操作的方法.
- 当服务器关闭时,会调用Filter的destroy方法来进行销毁操作.
FilterConfig:
在Filter的init方法上有一个参数,类型就是FilterConfig.
FilterConfig它是Filter的配置对象,它可以完成下列功能
1.获取Filter名称
2.获取Filter初始化参数
3.获取ServletContext对象。
在Filter中获取一个FIlterConfig对象
public class Myfilter implements Filter {
private FilterConfig config;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.config = filterConfig;
System.out.println("在启动服务器的时候就创建");
}
}
Filter配置:
基本配置如上所述
<filter>
<filter-name>filter名称</filter-name>
<filter-class>Filter类的包名.类名</filter-class>
</filter>
<filter-mapping>
<filter-name>filter名称</filter-name>
<url-pattern>路径</url-pattern>
</filter-mapping>
1、< url-pattern>
完全匹配 以”/demo1”开始,不包含通配符*
目录匹配 以”/”开始 以*结束
扩展名匹配 .xxx 不能写成/.xxx
2、< servlet-name>:它是对指定的servlet名称的servlet进行拦截的。
3、< dispatcher>:可以取的值有 REQUEST FORWARD ERROR INCLUDE
作用是:当以什么方式去访问web资源时,进行拦截操作.
- REQUEST 当是从浏览器直接访问资源,或是重定向到某个资源时进行拦截方式配置的 它也是默认值
- FORWARD 它描述的是请求转发的拦截方式配置
- ERROR 如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。
- NCLUDE 如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用
<filter-mapping>
<filter-name>MyFilter3</filter-name>
<url-pattern>/*</url-pattern>
<!--拦截所有的include和request请求-->
<dispatcher>INCLUDE</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
案例:创建一个get,post编码过滤器
使用适配器模式,重写HttpServletRequest
package com.yanglin.filter;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Map;
/**
* Created by yanglin on 2016/10/31.
*/
public class Globalfilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
}
@Override
public void destroy() {
}
}
class MyRequest extends HttpServletRequestWrapper{
private HttpServletRequest hsr ;
boolean flg = true;
public MyRequest(HttpServletRequest request) {
super(request);
this.hsr = request;
}
@Override
public String getParameter(String name) {
Map<String, String[]> map = this.getParameterMap();
return map.get(name)[0];
}
@Override
public Map<String, String[]> getParameterMap() {
Map<String, String[]> map = hsr.getParameterMap();// 乱码
if(flg){
for (Map.Entry<String, String[]> m : map.entrySet()) {
String[] values = m.getValue();
for (int i = 0; i < values.length; i++) {
try {
values[i] = new String(
values[i].getBytes("iso-8859-1"), "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
flg = false;
}
return map;
}
@Override
public String[] getParameterValues(String name) {
Map<String, String[]> map = getParameterMap();
return map.get(name);
}
}
web.xml注册为所有的请求都需要过滤
<!--配置拦截-->
<filter>
<filter-name>Myfilter</filter-name>
<filter-class>com.yanglin.filter.Globalfilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Myfilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>