playframework 拦截器

我觉得play的拦截器有点AOP的思想,相当于struts的filter,play的拦截器使用注解方式实现的。

源码定义了这么几种注解:@before、@after、@catch、@finally 可谓是三百六十度无死角的拦截了。

标注了@Before的方法会在该类的所有方法之前执行,举例:

[java] view plaincopy

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

当请求进入Admin时会先检查这个类中是否有@before注解,有就优先执行。

当然还有高级点的特性,如果您不想拦截某些方法,您可以使用unless表明,这样如果用户发来login的请求就不会执行@Before了,如下:

[java] view plaincopy

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

同样,您也可以使用only属性,指定需要拦截的请求:

[java] view plaincopy

  1. public class Admin extends Controller {
  2. @Before(only={"login","logout"})
  3. static void doSomething() {
  4. }
  5. }

@After注解的道理是一样的,不过是执行了请求方法之后执行

[java] view plaincopy

  1. public class Admin extends Controller {
  2. @After
  3. static void log() {
  4. Logger.info("Action executed ...");
  5. }
  6. public static void index() {
  7. List<User> users = User.findAll();
  8. render(users);
  9. }
  10. }


下面说说@Catch注解,这个很好用,当程序抛出异常时候可以被标注了@Catch的方法抓住,我们可以在里面做一些必要的操作,比如rollback等。

[java] view plaincopy

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


对了,其中的prioroty属性可以设置执行顺序的优先级,priority=1是最先执行的。

[java] view plaincopy

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


@Finally注解的方法和java的finally一样,不管有没有执行成功都会进入该方法,我们可以在里面打印日志:

[java] view plaincopy

  1. public class Admin extends Controller {
  2. @Finally
  3. static void log(Throwable e) {
  4. if( e == null ){
  5. Logger.info("action call was successful");
  6. } else{
  7. Logger.info("action call failed", e);
  8. }
  9. }
  10. public static void index() {
  11. List<User> users = User.findAll();
  12. render(users);
  13. }
  14. }

上述所有的注解作用域都是类级别的,如果您想对另外的类也起作用,请用@With标签:

[java] view plaincopy

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

实现的原理应该是这样:socket请求发过来的时候,play 的路由会去匹配进入哪个Controller,然后看这个Controller里面有哪些系统标签,然后按规定好的执行顺序依次执行,这就是所谓的拦截了。(有时间把源码分析也一起发出来)

知道原理,我们就可以写自己的拦截器了,比如权限管理:在每个需要权限的方法上加上自定义的权限注解如:@MyAnatation(priority=1),用户发起请求——@Before拦截——从登录token拿到用户信息——查看该用户所有权限ID——对比自定义注解的priority——priority在权限ID中则允许访问,不包含返回无此权限信息。

[java] view plaincopy

  1. @Before(priority = 1)
  2. public static void doAuth(){
  3. Annotation annotation =  request.invokedMethod.getAnnotation(MyAnotation.class);
  4. if(annotation !=null){
  5. //鉴权开始
  6. QicFunction function =  (QicFunction)annotation;
  7. //todo
  8. }
  9. }

有了这种思想,我们可以做任何自定义的拦截行为,谁也拦不住。

最后,要提醒自己,路漫漫其修远兮,吾将上下而求索。加油啊!

时间: 2024-09-22 10:49:38

playframework 拦截器的相关文章

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

1.首先要明确什么是拦截器.什么是过滤器 1.1 什么是拦截器: 拦截器,在AOP(Aspect-Oriented Programming)中用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作.拦截是AOP的一种实现策略. 在Webwork的中文文档的解释为--拦截器是动态拦截Action调用的对象.它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行.同时也是提供了一种可以提取action中可重用的部分的方式.

微信小程序之页面拦截器

场景 小程序有52个页面,其中13个页面无需任何身份,另外39个页面需要系统角色.对于这39个页面,如果微信用户没有系统角色,则跳转到登录页.是否有系统角色信息需要通过异步请求来获取. 需求分析&实现 对需求进行抽象,其实要的就是一个过滤器,对小程序页面的访问进行过滤,符合条件的通过,不符合条件进行其他处理. 使用过php的laravel框架的童鞋,肯定一下子就联想到了laravel框架的http中间件:HTTP 中间件提供一个方便的机制来过滤进入应用程序的 HTTP 请求,例如,Laravel

SpringMvc拦截器小测试

前言 俗话说做项目是让人成长最快的方案,最近小编写项目的时候遇到了一个小问题.小编在项目中所负责的后台系统,但是后台系统是通过系统的页面是通过ifame联动的,那么这时候问题就来了,后台所做的所有操作都是联动操作(都是基于所联动的)那么我后台所做的所有操作都是基于后台用户登录的情况下所做的.但是在联动中中所有页面都是单独存在的,如果要解决这个问题就需要在做操作之前判断用后台用户是否已经登录.想知道小编是如何实现的那就接着往下看. 简介 Spring MVC的拦截器不仅可实现Filter的所有功能

7.添加基于Spring的WebService拦截器

客户端拦截器: public class AccountInterceptor extends AbstractPhaseInterceptor<SoapMessage>{ private String name; private String password; public AccountInterceptor(String name,String password) { //Phase值决定了拦截器什么时候拦截到消息 //PRE_PROTOCOL准备请求时拦截 super(Phase.P

struts2学习笔记---自定义拦截器

什么是拦截器? struts2中拦截器分为Struts2定义好的拦截器和自定义的拦截器.其作用是在一个Action执行之前进行拦截,在Action执行之后又加入某些操作. 实现原理 当请求一个Action时,struts2会查找配置文件,并根据这个Action的配置实例化对应的拦截器对象,然后串成一个列表(list),最后一个一个地调用列表中的拦截器. 拦截器的执行流程 1.对Action进行预处理.(正序执行) 2.拦截器自身决定该不该执行后续的拦截器(由invoke()方法的返回值决定).

使用方法拦截器MethodInterceptor和AOP统一处理log

对每个接口的请求记录log的方法有很多种,比如用filter.mvc interceptor.method interceptor等.如果需要记录请求消息的payload,前两种不适用.下面介绍第三种的实现方法. 第一步:引入包依赖 <span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"></span><pre name=&

过滤器、监听器、拦截器的区别

1.过滤器 Servlet中的过滤器Filter是实现了javax.servlet.Filter接口的服务器端程序,主要的用途是过滤字符编码.做一些业务逻辑判断等.其工作原理是,只要你在web.xml文件配置好要拦截的客户端请求,它都会帮你拦截到请求,此时你就可以对请求或响应(Request.Response)统一设置编码,简化操作:同时还可进行逻辑判断,如用户是否已经登陆.有没有权限访问该页面等等工作.它是随你的web应用启动而启动的,只初始化一次,以后就可以拦截相关请求,只有当你的web应用

spring mvc 方法注解拦截器

应用场景,在方法级别对本次调用进行鉴权,如api接口中有个用户唯一标示accessToken,对于有accessToken的每次请求可以在方法加一个拦截器,获得本次请求的用户,存放到request或者session域. python中,之前在python flask中可以使用装饰器来对方法进行预处理,进行权限处理 先看一个实例,使用@access_required拦截: @api.route('/post_apply') @access_required def apply():     "&q

【struts2】预定义拦截器

1)预定义拦截器 Struts2有默认的拦截器配置,也就是说,虽然我们没有主动去配置任何关于拦截器的东西,但是Struts2会使用默认引用的拦截器.由于Struts2的默认拦截器声明和引用都在这个Struts-default.xml里面,因此我们需要到这个文件的struts-default包里去看一下.定义如下: 1 <interceptors> 2 <interceptor name="alias" class="com.opensymphony.xwor