拦截器
用过Spring MVC的朋友一定对Spring的拦截器并不陌生,Forest也同样支持针对Forest请求的拦截器。
如果您想在很多个请求发送之前或之后做一些事情(如打印日志、计数等等),拦截器就是您的好帮手。
构建拦截器
定义一个拦截器需要实现com.dtflys.forest.interceptor.Interceptor接口
Interceptor
接口带有一个泛型参数,其表示的是请求响应后返回的数据类型。
Interceptor<String>即代表返回的数据类型为 String
。
拦截器与 Spring 集成
若我要在拦截器中注入 Spring 的 Bean 改如何做?
在拦截器中传递数据
在Forest中,拦截器是基于单例模式创建的,也就是说一个拦截器类最多只能对应一个拦截器实例。
那么以下这种通过共享变量的方式就可能造成错误:
若有两个请求同时进入该拦截器(请求1 url=...?name=A1, 请求2 url=...?name=A2), 而最后当请求1进入onSuccess
方法时,应该打印出 name = A2
,却因为之前执行了请求2的beforeExecute
方法,将类变量name
的值改成了A2
,
所以最终打印出来的是 name = A2
(其实应该是 name = A1
),这明显是错误的。
那该如何做能在传递数据的同时避免这类问题呢?
方法也很简单,就是将您要传递的数据与请求对象绑定在一起,比如在 onSuccess
中调用request.getQuery
方法。
虽然这种方法能够解决并发问题,但有个明显的限制:如果要传递的数据不想出现在请求中的任何位置(包括URL、请求头、请求体),那就无能为力了。
这时候就要使用 ForestRequest
的扩展绑定数据的方法了。
Attribute
在拦截器中使用addAttribute
方法和getAttribute
方法来添加和获取Attribute
。
Attribute
是和请求以及所在拦截器绑定的属性值,这些属性值不能通过网络请求传递到远端服务器。
而且,在使用getAttribute
方法时,只能获取在相同拦截器,以及相同请求中绑定的Attribute
,这两个条件缺一不可。
Attachment
可以使用ForestRequest
对象的addAttachment
方法和getAttachment
方法来添加和获取Attachment
。
Attachment
是和请求绑定的附件属性值,这些值不能通过网络请求传递到远端服务器。
而且,在使用getAttachment
方法时,只能获取在相同请求中绑定的Attachment
,但不必是相同的拦截器。
Attribute与Attachment的区别
Attribute
和Attachment
都是能通过请求进行绑定的数据传递方式,但也有所不同。
绑定请求 | 绑定拦截器 | |
---|---|---|
Attribute | ✔ | ✔ |
Attachment | ✔ | ✘ |
配置拦截器
Forest有三个地方可以添加拦截器:@Request
、@BaseRequest
、全局配置,这三个地方代表三个不同的作用域。
@Request上的拦截器
若您想要指定的拦截器只作用在指定的请求上,只需要在该请求方法的@Request
注解中设置interceptor
属性即可。
@Request
中拦截器可以配置多个:
友情提示
@Request
上的拦截器只会拦截指定的请求
@BaseRequest 上的拦截器
若您想使一个interface
内的所有请求方法都指定某一个拦截器,可以在@BaseRequest
的interceptor
中设置
如以上代码所示,SimpleClient
接口中的send1
、send2
、send3
方法都被会SimpleInterceptor
拦截器拦截
@BaseRequest
也如@Request
中的interceptor
属性一样,可以配1到多个拦截器,如代码所示:
全局拦截器
若要配置能拦截项目范围所有Forest请求的拦截器也很简单,只要在全局配置中加上interceptors
属性即可