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下面看到这些文件:
初始化webx 在web.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加在excludes
或passthru
参数里。这样,WebxFrameworkFilter就会排除或略过指定的URL。 其中passthru
和excludes
的区别在于,如果一个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
接到请求之后又做了哪些事儿呢,可以看一下下面这两张图:
总结起来就是WebxFrameworkFilter
接受到所有请求之后,就会调用WebxRootController
。
从这里开始,进入Spring的世界 此后所有的对象:WebxRootController
、WebxController
、RequestContext
、Pipeline
等, 全部是通过SpringExt
配置在Spring Context
中的。
WebxRootController
对象存在于root context
中,它被所有子应用所共享。
它会创建RequestContext
实例 从而增强request
、response
、session
的功能。
接下来会进行子应用的选择——WebxController
对象会被调用。 WebxController
对象是由每个子应用独享的,子应用app1和app2可以有不同的WebxController
实现。默认的实现,会调用pipeline
。
Pipeline
是WebX中最强大的功能之一。通过定制一个Pipeline
(管道)中Valve
(阀门)的组合,可以控制如何处理一个进来的请求。 Pipeline也是由各子应用自己来配置的。
假如pipeline碰到无法处理的请求,如静态页面、图片等,pipeline应当执行 valve强制退出。
然后WebxRootController
就会“放弃控制” —— 这意味着request
将被返还给/WEB-INF/web.xml
中定义的servlet
、filter
或者返还给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。