过滤器
By:zozoh<zozohtnt@gmail.com>

什么是过滤器?

Top

请你再一次回顾这张图:

一个 HTTP 请求,过滤器是第一组被执行的对象。同适配器不同的是,一个请求中,可以执行多个过滤器。

如何使用过滤器?

Top

通过 @Filters 注解。

注解 '@Filters' 的值是一个 '@By' 注解的数组,它可以声明在这三个地方

  1. 入口函数
  2. 子模块
  3. 主模块

其中入口函数的 @Filters 优先级更高,其次是子模块,最后是主模块。

就是说,你在入口模块声明了两个过滤器:

@Filters({@By(type=Filter1.class), @By(type=Filter2.class)})
public final class MainModule{
	...

在某一个入口函数上声明了一个空的过滤器数组:

...
@At
@Filters
public String myFunction(){
	...

那么,这个入口函数将不会应用任何过滤器。

使用内置过滤器

Top
@Filters(@By(type=CheckSession.class, args={"user", "/login.jsp"}))

CheckSession 是 Nutz.Mvc 为你内置的一个唯一的过滤器,它的构造函数需要两个参数:

定制你自己的过滤器

Top

你当然可以定制你自己的过滤器,请注意过滤器接口代码:

public interface ActionFilter {
	View match(ActionContext context);
}

根据 HttpRequest 对象,你的过滤器需要决定返回值是:

如果你的过滤器返回的是 null,Nutz.Mvc 会继续执行下一个过滤器,如果全部的过滤器都返回 null它就会调用适配器,进行后面的操作

交给 Ioc 容器管理

Top

如果你的 Filter 需要比较灵活的配置,你可以将它交由 Ioc 容器负责

@Filters(@By(type=MyFilter.class, args={"ioc:myFilter"}))

其中 "myFilter" 就是你这个过滤器在 Ioc 容器中的名字。关于 Ioc 容器更多的知识,请参看Ioc 手册

请注意 如果你要让 Ioc 容器管理你的过滤器,你的应用必须已经声明了一个 Ioc 容器。 如何在Mvc 框架中声明 Ioc 容器,请参看 同 Ioc 容器一起工作

如果Filter实现了Processor接口

Top

从1.r.55开始,如果一个类同时实现了ActionFilter和Processor,那么事情就变得有趣得多

public class SayHiFilterProcessor extends AbstractProcessor implements ActionFilter  {

	public View match(ActionContext ac) {
		log.debug("match? maybe.")
		return null;
	}
	
	public void process(ActionContext ac) throws Throwable {
		log.debug("before doNext");
		doNext(ac);
		log.debug("after doNext");
	}
}

假设入口方法仅输出一句日志"你好",那么就能看到这样的日志

DEBUG - match? maybe.
DEBUG - before doNext
INFO  - 你好
DEBUG - after doNext

可以看到,类似于aop的环绕式输出,关于Processor接口的更多信息,请参考动作链