webx- Filter, Request Contexts, Pipeline

Filter

1.工作原理

Request Contexts服务

事实上,你可以把Request Context看作是HttpServletRequest和HttpServletResponse这两个对象总和,除此之外,多个Request Context可以被串起来,被称为Request Context Chain。

Request Context在预处的时候,可以利用HttpServletRequestWrapper和HttpServletResponseWrapper来包装和修改request和response,这一点和filter相同,最先的Request Context成为最内层的包装,最后的Request Context成为最外层的包装。

webx目前提供了以下几种request context的实现

 

名称功能
<basic>提供基础安全特性,例如:过滤response headers、cookies,限制cookie的大小等
<buffered>缓存response中的内容
<lazy-commit>延迟提交response
<parser>解析参数
<rewrite>重定请求的URL和参数
<session>一套可扩展的session框架
<set-locale>设置Locale区域和charset字符集编码

 

1.使用

 

 

<?xml version="1.0" encoding="UTF-8" ?>
<beans:beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:services="http://www.alibaba.com/schema/services"
xmlns:request-contexts="http://www.alibaba.com/schema/services/request-contexts"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.alibaba.com/schema/services
http://localhost:8080/schema/services.xsd
http://www.alibaba.com/schema/services/request-contexts
http://localhost:8080/schema/services-request-contexts.xsd
http://www.springframework.org/schema/beans
http://localhost:8080/schema/www.springframework.org/schema/beans/spring-beans.xsd
">
...
<services:request-contexts xmlns="http://www.alibaba.com/schema/services/request-contexts">
<basic />
<buffered />
<lazy-commit />
<parser />
<set-locale defaultLocale="zh_CN" defaultCharset="UTF-8" />
<!-- Optional -
<session />
<rewrite />
-->
</services:request-contexts>
<services:upload sizeMax="5M" />
</beans:beans>


2.注入request作用域的对象

 

 

对象类型作用域
ServletContextSingleton scope
HttpServletRequestRequest scope
HttpServletResponseRequest scope
HttpSessionSession scope
所有RequestContext对象,如:ParserRequestContextRequest scope

 

在Spring中不能把一个短期对象如request、response和request Context注入到singleton对象,然而在webx中,这样做是可以的,因为Request Context服务对上表所列的短期对象作了特殊的处理,使它们可以被注入到singleton对象中。事实中,被注入的只是一个“空壳”,真正的对象是在被访问到的时候才会从线程中取得。

 

 

Pipeline服务

pipeline只能控制流程,不能改变request和response。

1.pipeline的使用

(1)创建一个valve

 

public class MyValve implements Valve {
public void invoke(PipelineContext pipelineContext) throws Exception {
System.out.println("valve started.");
pipelineContext.invokeNext(); // 调用后序valves
System.out.println("valve ended.");
}
}


pipeline.xml

 

 

<services:pipeline xmlns="http://www.alibaba.com/schema/services/pipeline/valves">
...
<valve class="com.alibaba.myapp.pipeline.MyValve" />
...
</services:pipeline>


(2)执行一个pipeline

 

 

@Autowired
private Pipeline myPipeline;
public void invokePipeline() {
PipelineInvocationHandle invocation = myPipeline.newInvocation();
invocation.invoke();
System.out.println(invocation.isFinished());
System.out.println(invocation.isBroken());
}

 

 

Pipeline对象是线程安全的,可被所有线程所共享。但PipelineInvocationHandler对象不是线程安全的,每次执行pipeline时,均需要取得新的invocation对象。


(3)调用子流程

子流程不过是另一个pileline对象而已。

 

public class MyNestableValve implements Valve {
private Pipeline subPipeline;
public void setSubPipeline(Pipeline subPipeline) {
this.subPipeline = subPipeline;
}
public void invoke(PipelineContext pipelineContext) throws Exception {
// 发起子流程,以当前流程的pipelineContext为参数
PipelineInvocationHandle subInvocation = subPipeline.newInvocation(pipelineContext);
subInvocation.invoke();
System.out.println(subInvocation.isFinished());
System.out.println(subInvocation.isBroken());
pipelineContext.invokeNext(); // 别忘了调用后序的valves
}
}

 

 

pipeline.xml配置文件

 

<services:pipeline xmlns="http://www.alibaba.com/schema/services/pipeline/valves">
...
<valve class="com.alibaba.myapp.pipeline.MyNestableValve" p:subPipeline-ref="subPipeline" />
...
</services:pipeline>

 


(4)中断一个pipeline

 

 

 

pipelineContext.breakPipeline(0); // level=0,中断当前pipeline
pipelineContext.breakPipeline(1); // level=1,中断上一级pipeline
pipelineContext.breakPipeline("label"); // 中断到指定label的上级pipeline
// 以上调用相当于:
pipelineContext.breakPipeline(pipelineContext.findLabel("label"));
pipelineContext.breakPipeline(Pipeline.TOP_LABEL); // 终止所有pipelines

 


(5)存取pipeline的状态

 

 

 

pipelineContext.index(); // 当前valve在pipeline中的序号
pipelineContext.level(); // 当前pipeline在所有子pipeline中的级别
pipelineContext.isBroken(); // 当前pipeline是否已经被中断
pipelineContext.isFinished(); // 当前pipeline的所有valves是否已经执行完
// 存取任意数据
pipelineContext.getAttribute(key);
pipelineContext.setAttribute(key, value);


(6)现成可用的valves

 

 

  • 无条件循环-<loop>
<services:pipeline>
<loop loopCounterName="count" maxLoopCount="10">
<valve />
<break-if test="..." />
</loop>
</services:pipeline>


循环变量loopCounterName将被保存在pipelineContext中,且可被其它的valve所访问。无条件循环一定要和<break>, <break-if>或<break-unless>等valves相配合。

  • 条件循环-<while>
<services:pipeline>
<while loopCounterName="count" test="count <= 2">
<valve />
</while>
<while maxLoopCount="10">
<conditions:condition class="..." />
<valve />
</while>
</services:pipeline>

 

  • 单条件分支-<if>
<services:pipeline>
<if test="1 == 2">
<valve />
</if>
<if>
<conditions:condition class="..." />
<valve />
</if>
</services:pipeline>

 

  • 多条件分支-<choose><when><otherwise>
<services:pipeline>
<choose>
<when test="1 == 2">
<valve />
</when>
<when>
<conditions:condition class="..." />
<valve />
</when>
<otherwise>
<valve />
</otherwise>
</choose>
</services:pipeline>

 

  • 无条件中断-<break>
<services:pipeline>
<loop>
<valve />
<break />
<valve />
</loop>
<loop>
<valve />
<loop>
<break levels="1" />
</loop>
<valve />
</loop>
<loop label="MY_LOOP">
<valve />
<loop>
<break toLabel="MY_LOOP" />
</loop>
<valve />
</loop>
</services:pipeline>

 

  • 有条件中断-<break-if> <break-unless>
<services:pipeline>
<loop loopCounterName="count">
<valve />
<break-if test="count > 2" />
<valve />
</loop>
<loop label="MY_LOOP">
<valve />
<break-if toLabel="MY_LOOP">
<conditions:condition class="..." />
</break-if>
<valve />
</loop>
<loop loopCounterName="count">
<valve />
<break-unless test="count <= 2" />
<valve />
</loop>
</services:pipeline>

 

  • 无条件退出整个pipeline-<exit>
<services:pipeline>
<loop>
<valve />
<loop>
<exit />
</loop>
<valve />
</loop>
</services:pipeline>

 

  • 异常捕获和finally处理-<try-catch-finally>
<services:pipeline>
<try-catch-finally>
<try>
<valve />
</try>
<catch exceptionName="myexception">
<valve />
</catch>
<finally>
<valve />
</finally>
</try-catch-finally>
</services:pipeline>


<catch>标签可以将捕获的异常以指定名称保存在pipelineContext中,以便其它valve取得。

  • 创建子流程
<services:pipeline>
<valve />
<sub-pipeline label="mylabel">
<valve />
</sub-pipeline>
<valve />
</services:pipeline>


(7)条件

Condition是一个简单的接口。

public interface Condition {
/**
* 如满足条件,则返回<code>true</code>。
*/
boolean isSatisfied(PipelineStates pipelineStates);
}

webx默认提供了一个JexlCondition,JEXL表达式是Apache的一个小项目,表达式语法见:http:// commons.apache.org/jexl/reference/syntax.html http:// commons.apache.org/jexl/reference/syntax.html

 

另外,webx还提供了三个组合式的条件。

  • <all-of>

要求所有条件均满足,相当于Java中的&&操作符。

<all-of>
<condition1 />
<condition2 />
<condition3 />
</all-of>

 

  • <any-of>
<any-of>
<condition1 />
<condition2 />
<condition3 />
</any-of>

 

  • <none-of>

要求所有条件均不满足。

<none-of>
<condition1 />
<condition2 />
<condition3 />
</none-of>


 

最后欢迎大家访问我的个人网站:1024s

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值