天道不一定酬所有勤
但是,天道只酬勤

webx3请求过程

webx初始化

可以使用命令:

mvn archetype:generate 
          -DgroupId=com.alibaba.webx 
          -DartifactId=helloworld3 
          -Dversion=1.0-SNAPSHOT 
          -Dpackage=com.alibaba.webx.helloworld 
          -DarchetypeArtifactId=archetype-webx-quickstart 
          -DarchetypeGroupId=com.alibaba.citrus.sample 
          -DarchetypeVersion=1.8
          -DinteractiveMode=false

来初始化一个webx应用。 创建好的web应用在WEB-INF下面看到这些文件:

QQ20151012-1

初始化webxweb.xml中将WebxContextLoaderListener作为一个ServletContextListener注册。

<listener>
    <listener-class>com.alibaba.citrus.webx.context.WebxContextLoaderListener</listener-class>
</listener>

这样在容器启动的过程中Webx Framework将会自动搜索webx.xml以及webx-开头的XML配置文件,并创建一组级联的Spring容器结构。Webx所创建的Spring容器完全兼容于Spring MVC所创建的容器,可被所有使用Spring框架作为基础的WEB框架所使用。 Webx Framework将会自动搜索/WEB-INF目录下的XML配置文件,并根据扫描到的webx配置文件创建具有级联关系的spring容器。比如:webx.xml对应根容器,而webx-app1.xml对应根容器下的一个子容器(sub container),如果还有webx-app2.xml,则对应根容器下的另一个子容器。子容器中的bean无法相互注入,但是根容器中的bean可以注入到子容器中。

接管请求

在web.xml中配置WebxFrameworkFilter,并根据自己业务需要配置webx的filter需要接管的URL pattern。默认情况下的配置是接管所有请求。

<filter>
    <filter-name>webx</filter-name>
    <filter-class>com.alibaba.citrus.webx.servlet.WebxFrameworkFilter</filter-class>
    <init-param>
        <param-name>excludes</param-name>
        <!-- 需要被“排除”的URL路径,以逗号分隔,如/static, *.jpg。适合于映射静态页面、图片。 -->
        <param-value>...</param-value>
    </init-param>
    <init-param>
        <param-name>passthru</param-name>
        <!-- 需要被“略过”的URL路径,以逗号分隔,如/myservlet, *.jsp。适用于映射servlet、filter。
                对于passthru请求,webx的request-contexts服务、错误处理、开发模式等服务仍然可用。 -->
        <param-value>...</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>webx</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping> 

当一个HTTP请求到达时,首先由WebxFrameworkFilter接手这个请求。如果你的web.xml中还有一些其它的servlet mappings,为了避免和Webx的URL起冲突,你可以把这些mapping加在excludespassthru参数里。这样,WebxFrameworkFilter就会排除或略过指定的URL。 其中passthruexcludes的区别在于,如果一个servlet或filter接手被webx passthru的请求时,它们还是可以访问到webx的部分服务。

初始化日志系统

Webx利用LogConfiguratorListener来初始化日志系统,会根据你当前应用所依赖的日志系统,来自动选择合适的日志配置文件:

假设你的应用依赖了logback的jar包,那么listener就会查找/WEB-INF/logback.xml,并用 它来初始化logback 如果你的应用依赖了log4j的jar包,那么listener也会很聪明地查找/WEB-INF/log4j.xml配置 文件 假如以上配置文件不存在,listener会使用默认的配置 —— 把日志打印在控制台上

<!-- 初始化日志系统 -->
<listener>
    <listener-class>com.alibaba.citrus.logconfig.LogConfiguratorListener</listener-class>
</listener>

WebX通过SetLoggingCotnextFilter对当前请求的信息打日志,比如:URL、referrer URL、query string等

<!-- 对当前请求的信息打日志 -->
<filter>
    <filter-name>mdc</filter-name>
    <filter-class>com.alibaba.citrus.webx.servlet.SetLoggingContextFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>mdc</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

webx请求处理

在初始化好webx之后,一个请求访问应用时,首先WebxFrameworkFilter会接手这个请求。在WebxFrameworkFilter接到请求之后又做了哪些事儿呢,可以看一下下面这两张图:

webx1

webx2

总结起来就是WebxFrameworkFilter接受到所有请求之后,就会调用WebxRootController

从这里开始,进入Spring的世界 此后所有的对象:WebxRootControllerWebxControllerRequestContextPipeline等, 全部是通过SpringExt配置在Spring Context中的。

WebxRootController对象存在于root context中,它被所有子应用所共享。

它会创建RequestContext实例 从而增强requestresponsesession的功能。

接下来会进行子应用的选择——WebxController对象会被调用。 WebxController对象是由每个子应用独享的,子应用app1和app2可以有不同的WebxController实现。默认的实现,会调用pipeline

Pipeline是WebX中最强大的功能之一。通过定制一个Pipeline(管道)中Valve(阀门)的组合,可以控制如何处理一个进来的请求。 Pipeline也是由各子应用自己来配置的。

假如pipeline碰到无法处理的请求,如静态页面、图片等,pipeline应当执行 valve强制退出。

然后WebxRootController就会“放弃控制” —— 这意味着request将被返还给/WEB-INF/web.xml中定义的servletfilter或者返还给servlet engine本身来处理。

Pipeline接到请求后会做这么几件事
初始化
设置日志系统的上下文
分析URL
CSRF安全校验

在分析URL时,会把用户请求的url转成target。分析完target之后会按照映射规则执行对应的Java类。

target映射成screen module类名的规则。

假设target为xxx/yyy/zzz,那么Webx Turbine会依次查找下面的screen模块:

screen.xxx.yyy.Zzz,
screen.xxx.yyy.Default,
screen.xxx.Default,
screen.Default。

target映射成screen template,以及target映射成layout template。

假设target为xxx/yyy/zzz,那么Webx Turbine会查找下面的screen模板:/templates/screen/xxx/yyy/zzz。Screen模板如果未找到,就会报404 Not Found错误。 找到screen模板以后,Webx Turbine还会试着查找下面的layout模板:

/templates/layout/xxx/yyy/zzz
/templates/layout/xxx/yyy/default
/templates/layout/xxx/default
/templates/layout/default

Layout模板如果找不到,就直接渲染screen模板;如果存在,则把渲染screen模板后的结果,嵌入到layout模板中。
Layout模板和screen模板中,都可以调用control。每个页面只有一个screen,却可以有任意多个controls。

(全文完)
欢迎关注HollisChuang微信公众账号
打赏

如未加特殊说明,此网站文章均为原创,转载必须注明出处。HollisChuang's Blog » webx3请求过程

分享到:更多 ()

HollisChuang's Blog

联系我关于我