webx- Filter, Request Contexts, Pipeline

前端之家收集整理的这篇文章主要介绍了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作用域的对象

对象类型 作用域
ServletContext Singleton scope
HttpServletRequest Request scope
HttpServletResponse Request scope
HttpSession Session scope
所有RequestContext对象,如:ParserRequestContext Request 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>

猜你在找的设计模式相关文章