拦截器

    1. 基于注解的方式 (类似PlayFramework)
    2. 通过继承写拦截器类

    该设计完全基于PlayFramework 1.x的方式

    在某方法上使用注解告诉ActFramework在执行该类中的所有请求响应器之前先调用该方法

    下面我们使用拦截器来创建一个安全检查:

    如果不需要拦截器拦截发送给某些响应器的请求,可以使用except参数来指定豁免清单:

    1. public class Admin extends Controller.Util {
    2. @Before(except="login")
    3. static void checkAuthentification() {
    4. if(session.get("user") == null) {
    5. redirect("/login");
    6. }
    7. }
    8. public void index() {
    9. Iterable<User> users = userDao.findAll();
    10. render(users);
    11. }
    12. }

    另一方面,你也可以使用only参数来指定该拦截器唯一作用于的响应器:

    1. public class Admin extends Controller.Util {
    2. public void doSomething() {
    3. }
    4. }

    @After

    标注有@After的方法在执行本类中所有的响应器之后被调用.

    如果某方法标注有@Catch,该方法在当前类的响应器抛出异常后被调用. 被抛出的异常作为参数传递给@Catch方法.

    1. public class Admin extends Controller.Util {
    2. @Catch(IllegalStateException.class)
    3. public void logIllegalState(Throwable throwable) {
    4. Logger.error("Illegal state %s…", throwable);
    5. }
    6. public void index() {
    7. List<User> users = userDao.findAllAsList();
    8. if (users.size() == 0) {
    9. throw new IllegalStateException("Invalid database - 0 users");
    10. }
    11. render(users);
    12. }
    13. }

    和通常的Java异常处理类似,你可以在@Catch拦截器方法中申明父类异常来捕获子类异常

    1. public class Admin extends Controller.Util {
    2. @Catch(value = Throwable.class, priority = 1)
    3. public void logThrowable(Throwable throwable) {
    4. // Custom error logging…
    5. Logger.error("EXCEPTION %s", throwable);
    6. }
    7. public void logIllegalState(Throwable throwable) {
    8. }
    9. public void index() {
    10. List<User> users = userDao.findAllAsList();
    11. if(users.size() == 0) {
    12. throw new IllegalStateException("Invalid database - 0 users");
    13. }
    14. render(users);
    15. }
    16. }

    @Finally

    标注有@Finally注解的方法在当前控制器的响应方法执行完成之后被调用,即便响应方法抛出异常,该拦截器也会被调用

    如果控制器继承了某个基类,在基类中定义的拦截器也适用于子类控制器

    使用@With注解来重用拦截器定义

    某个定义了拦截器的类:

    1. public class Secure extends Controller.Util {
    2. @Before
    3. static void checkAuthenticated() {
    4. if(!session.containsKey("user")) {
    5. unAuthorized();
    6. }
    7. }
    8. }

    控制器类:

    1. @With(Secure.class)
    2. public class Admin extends MyOtherBaseClass {
    3. }

    实现拦截器接口

    基于注解的拦截器非常轻量,不过只适用于定义或这引用了拦截器的控制器。如果需要实现全局拦截,可以通过继承XxxInterceptor来实现

    上面的代码拦截所有的请求,检查是否有fmt参数,如果发现fmt参数则设置相应的Accept头。

    类似的拦截器接口还有:

    1. act.handler.builtin.controller.AfterInterceptor