Valve用于控制请求的执行流程。它采用责任链的设计模式(类似于struts的拦截器)。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.");
}
}
<services:pipeline xmlns="http://www.alibaba.com/schema/services/pipeline/valves">
...
<valve class="com.alibaba.myapp.pipeline.MyValve" />
...
</services:pipeline>
调用一个阀。可以通过Autowired获取一个阀。
@Autowired
private Pipeline myPipeline;
public void invokePipeline() {
PipelineInvocationHandle invocation = myPipeline.newInvocation();
invocation.invoke();
}
一个valve可以调用另外一个Pipeline。可以中断任意一个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
内置valve。
loop。
<loop loopCounterName="count" maxLoopCount="10">
<valve />
<break-if test="..." />
</loop>
<while maxLoopCount="10">
<conditions:condition class="..." />
<valve />
</while>
<if>
<conditions:condition class="..." />
<valve />
</if>
<choose>
<when test="1 == 2">
<valve />
</when>
<when>
<conditions:condition class="..." />
<valve />
</when>
<otherwise>
<valve />
</otherwise>
</choose>
在循环中使用
<exit />
在循环中使用
<break-if test="count > 2" />
<break-if toLabel="MY_LOOP">
<conditions:condition class="..." />
</break-if>
<break-unless test="count <= 2" />
<try-catch-finally>
<try>
<valve />
</try>
<catch exceptionName="myexception">
<valve />
</catch>
<finally>
<valve />
</finally>
</try-catch-finally>
条件支持jexl和自定义的condition类。
<if>
<conditions:jexl-condition expr="loopCount == 2" />
<break />
</if>
等价:
<if test="loopCount == 2">
<break />
</if>
<all-of>
<condition1 />
<condition2 />
<condition3 />
</all-of>
<any-of>
<condition1 />
<condition2 />
<condition3 />
</any-of>
<none-of>
<condition1 />
<condition2 />
<condition3 />
</none-of>
下面介绍一下常见的阀门。
analyzeURL。分析URL,作用是得到target。它有一个homepage参数,作用是默认页面。
choose。相当于java中的switch语句。条件可以通过两种属性指定,target-extension-condition或者target-condition。下面是choose语句的例子。
<choose>
<when>
<pl-conditions:target-extension-condition extension="null, vm, jsp" />
...
</when>
<when>
<pl-conditions:target-extension-condition extension="do" />
...
</when>
<otherwise>
...
</otherwise>
</choose>
performAction。执行Action来处理表单。webx中的Action和其他框架中的不一样,这里只处理表单。其他的框架中可能还会在Action中渲染页面。
performTemplateScreen。它的作用是查找对应的Screen代码,并执行。如果target为xxx/yyy/zzz那么框架会依次寻找screen.xxx.yyy.Zzz、screen.xxx.yyy.Default、screen.xxx.Default、screen.Default,并调用它的execute(Context,HttpServletRequest)方法。在哪里寻找这些类呢?可以在webx.xml中的module-loader/search-packages中指定根包。
renderTemplate。渲染模板。如果target是xxx/yyy/zzz那么框架会依次尝试寻找/templates/screen/xxx/yyy/zzz、/templates/screen/xxx/yyy/default、/templates/screen/xxx/default、/templates/screen/default。如果没有找到模板,会报404的错误。找到screen模板以后,框架还会尝试寻找layout:/templates/layout/xxx/yyy/zzz、/templates/layout/xxx/yyy/default等。
breakUnlessTargetRedirected。跳出循环的条件。如果有内部重定向发生,那么跳出循环。