当前位置: 代码迷 >> Web前端 >> java web 过滤器跟拦截器的区别和使用
  详细解决方案

java web 过滤器跟拦截器的区别和使用

热度:1651   发布时间:2014-01-17 15:01:00.0
java web 过滤器和拦截器的区别和使用

1、首先要明确什么是拦截器、什么是过滤器

? ?1.1 什么是拦截器:?

? ? 拦截器,在AOP(Aspect-Oriented Programming)中用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作。拦截是AOP的一种实现策略。?

? ?在Webwork的中文文档的解释为――拦截器是动态拦截Action调用的对象。它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行。同时也是提供了一种可以提取action中可重用的部分的方式。?

? ? 谈到拦截器,还有一个词大家应该知道――拦截器链(Interceptor Chain,在Struts 2中称为拦截器栈 ? ? ? ? ? Interceptor Stack)。拦截器链就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。?

1.2. ? ?拦截器的实现原理:?

?大部分时候,拦截器方法都是通过代理的方式来调用的。Struts 2的拦截器实现相对简单。当请求到达Struts 2的ServletDispatcher时,Struts 2会查找配置文件,并根据其配置实例化相对的拦截器对象,然后串成一个列表(list),最后一个一个地调用列表中的拦截器。

1.3?什么是过滤器

过滤器是一个程序,它先于与之相关的servlet或JSP页面运行在服务器上。过滤器可附加到一个或多个servlet或JSP页面上,并且可以检查进入这些资源的请求信息。在这之后,过滤器可以作如下的选择:

①以常规的方式调用资源(即,调用servlet或JSP页面)。

②利用修改过的请求信息调用资源。

③调用资源,但在发送响应到客户机前对其进行修改。

④阻止该资源调用,代之以转到其他的资源,返回一个特定的状态代码或生成替换输出。

?

1.4 Servlet过滤器的基本原理

在Servlet作为过滤器使用时,它可以对客户的请求进行处理。处理完成后,它会交给下一个过滤器处理,这样,客户的请求在过滤链里逐个处理,直到请求发送到目标为止。例如,某网站里有提交“修改的注册信息”的网页,当用户填写完修改信息并提交后,服务器在进行处理时需要做两项工作:判断客户端的会话是否有效;对提交的数据进行统一编码。这两项工作可以在由两个过滤器组成的过滤链里进行处理。当过滤器处理成功后,把提交的数据发送到最终目标;如果过滤器处理不成功,将把视图派发到指定的错误页面。

?

2、拦截器与过滤器的区别 :?

? ? ?1. 拦截器是基于java的反射机制的,而过滤器是基于函数回调。

? ? ?2. 拦截器不依赖与servlet容器,过滤器依赖与servlet容器。?

? ? ?3. 拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。

? ? ?4. 拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。?

? ? ?5. 在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次

?

?

拦截器的代码实现(以struts2为例):

1、在xml文件中如何定义拦截器

<interceptors>

?<interceptor name="filterIPInterceptor"

? ? ? ? ? ? ? ? ? ? ? ? ?class="com.xxxx.web.FilterIPActionInterceptor" />

<interceptor-stack name="filterIPStack">

<interceptor-ref name="defaultStack" />

? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

<interceptor-ref name="filterIPInterceptor" />

</interceptor-stack>

</interceptors>

?

2、怎么遍别写自定义拦截器?

?

public class FilterIPActionInterceptor extends AbstractInterceptor

{

? ? /** 日志控制. */

? ? private final Log log = LogFactory.getLog(getClass());

?

? ? /**

? ? ?* @see com.opensymphony.xwork2.interceptor.AbstractInterceptor#intercept(com.opensymphony.xwork2.ActionInvocation)

? ? ?*/

? ? @Override

? ? @SuppressWarnings("unchecked")

? ? public String intercept(ActionInvocation invocation) throws Exception

? ? {

? ? ? ? String result = null;

? ? ? ? // 获得当前方法名.

? ? ? ? String methodName = invocation.getInvocationContext().getName();

? ? ? ? String currIp = null;

? ? ? ? try

? ? ? ? {

? ? ? ? ? ? if (invocation.getAction() instanceof PortletAction)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? PortletAction action = (PortletAction) invocation.getAction();

? ? ? ? ? ? ? ? currIp = action.getRequest().getRemoteAddr();

? ? ? ? ? ? }

? ? ? ? ? ? String ip = ApplicationResource.getHotValue("ALLOW_CACHE_IP");

?

? ? ? ? ? ? if (StringUtils.isBlank(ip) || StringUtils.isBlank(currIp))

? ? ? ? ? ? {

? ? ? ? ? ? ? ? log.error("允许刷新的IP不存在或当前请求的IP非法.");

? ? ? ? ? ? ? ? throw new NoAllowIPException();

? ? ? ? ? ? }

? ? ? ? ? ? else

? ? ? ? ? ? {

? ? ? ? ? ? ? ? String[] ips = ip.split(",");

? ? ? ? ? ? ? ? boolean errorIp = true;

? ? ? ? ? ? ? ? for (String s : ips)

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? if (s.equals(currIp))

? ? ? ? ? ? ? ? ? ? ? ? errorIp = false;

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? // 判断IP

? ? ? ? ? ? ? ? if (errorIp)

? ? ? ? ? ? ? ? ? ? throw new NoAllowIPException();

? ? ? ? ? ? }

? ? ? ? ? ? result = invocation.invoke();//调用被拦截的方法

? ? ? ? }

? ? ? ? catch (Exception e)

? ? ? ? {

? ? ? ? ? ? log.error("异常类名:" + invocation.getAction().getClass());

? ? ? ? ? ? log.error("异常方法:" + methodName, e);

? ? ? ? ? ? throw e;

? ? ? ? }

?

? ? ? ? return result;

? ? }

?

}

?

?

?

3、怎么编写过滤器

?

? ? ?1、在web.xml里面配置自定义的拦截器

? ? ? ? <filter>

<filter-name>Redirect Filter</filter-name>

<filter-class>com.xx.filter.RedirectFilter</filter-class>

</filter>

?

<filter-mapping>

<filter-name>Redirect Filter</filter-name>

<url-pattern>/xx/xx/*</url-pattern>

?

</filter-mapping>

?

? ? 2、如何编写自定义的拦截器

public class RedirectFilter implements Filter {

? ? ? ?public void doFilter(ServletRequest request, ServletResponse response,

? ? ? ? ? ? ? FilterChain filterChain) throws IOException, ServletException {

? ? // 获取URL

? ?Long startTime = null;

? ? ? ? if (log.isDebugEnabled())

? ? ? ? {

? ? ? ? ? ? startTime = System.currentTimeMillis();

? ? ? ? }

? ? ? ? ? ? ? HttpServletRequest httpRequest = (HttpServletRequest) request;

? ? ? ? ? ? ? ? ? ? ? ? ? String url = httpRequest.getRequestURL().toString();

? ? ? ? ? ? ? ? ? ? ? if (url == null || url.trim().length() == 0) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? return;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?}

? ? ? ? ? ? ? ? ? ? ?if (url.indexOf(luceneCreateMapping) != -1

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? || url.indexOf(luceneSearchMapping) != -1) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?doFilterForxxx(request, response, url);

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} else {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?doxxxx(request, response, url);

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ?if (log.isDebugEnabled())

? ? ? ? {

? ? ? ? ? ? long endTime = System.currentTimeMillis();

? ? ? ? ? ? Thread currentThread = Thread.currentThread();

? ? ? ? ? ? String threadName = currentThread.getName();

? ? ? ? ? ? log.debug("[" + threadName + "]" + "< "

? ? ? ? ? ? ? ? ? ? + this.getClass().getName() + " " + url + " "

? ? ? ? ? ? ? ? ? ? + (endTime - startTime) + " ms");

? ? ? ? }

// 激活下一个Filter

?filterChain.doFilter(request, response);

?

? ? ? ? }

}

?

  相关解决方案