Webx 核心机制图文介绍。
在本文中的Webx都是指webx3.0.11。
Webx的主题功能都是暴露成服务组件,主要的服务组件如下:
服务组件
1、RequestContext
2、Pipeline
3、资源载入:Classpath路径载入,本地路径路径载入,远程路径路径载入。
4、模板引擎:Velocity,Freemark,JSP。
5、邮件服务:基于JavaMail,纯文本邮件,HTML邮件,带附件邮件,基于模板的邮件。
6、表单
校验器:必填项,日期格式,字符串格式,数字格式,邮件地址格式,条件选择语句,文件上传校验
JEXL表达式:校验失败结果的Validator Message。
7、映射规则:后缀映射,URL和类路径映射。
8、URI风格:Servlet风格,Turbine风格。
9、资源上传:基于commons-fileupload。最重要的组件有两个,RequestContext和Pipeline,下面会对这两个服务进行分析。
Request Context机制分析
RequestContext只处理和上下文参数有关的信息,不干涉页面流程。在官方文档中有一个时序图可以大概的展示了RequestCntext机制,如下图所示:
一切起源与一个Http请求,Servlet引擎俘获请求,首先交给WebxFrameworkFilter进行处理。
第一步、WebxFrameworkFilter处理过程,这个一个标准Filter,对请求进行拦截。拦截之后会判断这个请求是否已经被过滤了,对于过滤的请求,Webx不进行处理。
第二步、WebxRootController处理过程,先将ServletContext,Request,Response封装成Webx的Context,这个Context就可以对应用本身的参数,Session,Request,Response的参数进行修改,这个Context也就是RequestContext参数处理的关键。最后,判断是否重定向,没有重定向则交友控制器进行(WebxController)处理,进入WebxController也就进入了Pipeline处理阶段。
第三步、Pipeline处理完毕之后,回到WebRootController的资源提交过程,这Commit是和前面的预处理对应的。需要提交的资源有:Session,Lazy,ReponseCommit,BufferedResponse。预处理和资源提交的过程如下图所示:
Pipeline机制分析
看完Pipeline的功能之后,再来看看Pipeline的一个执行顺序图,知道一个它运行时的概况:
开始节点,此处的开始承接了RequestContext,在RequestContext预处理之后,初始化了一个WebxController,这个控制器就是Pipeline的全过程,整个过程就是一个链式调用的过程,根据事先配置好的阀,顺序调用每一个阀。
以下图的配置进行分析:
第一步、PipelineInvocationHandle.invoke(),进顺序调用。
第二步、AnalyzeURLValve,分析Action类路径和方法调用,为后续的前置Action操作做准备,这个阀在带有Action的页面,是必备的,否则会报错。
第三步、CheckCsrfTokenValve,防止csrf攻击,防止重复提交同一表单。Csrf中午翻译是跨站请求伪造,是一种对网站的恶意利用。
第四步、ChooseValve,这里根据条件进行渲染的跳转。有三种,null后缀(通常映射.vm);json后缀;.do后缀。Null一般通常映射Action,然后渲染页面;json通常映射, 将screen所返回的结果转换成json格式并输出。.do后缀通常直接映射一个后台类,像Servlet一样返回一个输出流给前端界面渲染。
第五步、PerformActionValve,首先根据form.xml的配置进行表单校验,跟着使用CGLIB框架,动态调用Action类。
第六步、RenderTemplateValve,根据配置的模板引擎,编译模板,返回结果字符串给前端界面渲染。
Pipeline的主要阀如下:
PrepareForTurbineValve*
初始化参数,使得参数在上下文可以被获取
AnalyzeURLValve*
解析URL,获取映射后台类和需要的运行时数据
SetLoggingContextValve
设置或清理日志
CheckCsrfTokenValve
防止csrf攻击和重复提交同一表单
假如request和session中的token不匹配,则出错,或显示expired页面。
GetResourceValve
从resource loader中装载资源,并直接显示的valve。
PageAuthorizationValve
页面权限校验
PerformActionValve
执行action module,通常用来处理用户提交的表单
PerformScreenValve
执行不带模板的screen
PerformTemplateScreenValve
执行带模板的screen
RenderTemplateValve
渲染模板。
RenderResultAsJsonValve
将screen所返回的结果转换成json格式并输出。
RequestHandlerValve
调用Spring MVC的HttpRequestHandler
SetBufferingValve
开关buffering
模板服务
Webx封装了一层抽象的模板服务TemplateService,自带了三种模板引擎的实现,其中常用的是Velocity,VelocityEngineImpl对Velocity框架进行包装,在pipeline的RenderTemplateValve会传递三个参数给VelocityEngineImpl,.vm路径,上下文参数Context,输出流。Context会被经过两次适配,第一次是适配成TemplateService的Context,第二次被适配成Velocity的Context,然后由org.apache.velocity.Template实例,根据这三个参数进行编译,最后将结果输出到输出流中。