我这边引出几个问题。
问题1,struts2 是怎么让 velocity 按照指定的 ResourceLoader 加载 vm 模板的?
?
首先,struts 默认的查找vm模板的路径有两种:
1,以 webapp 为相对路径下面去找
2,从 classpath 下面去找
那么看下面的代码 org.apache.struts2.views.velocity.VelocityManager:
- private ? void ?applyDefaultConfiguration(ServletContext?context,?Properties?p)?{??
- ????????//?ensure?that?caching?isn't?overly?aggressive ??
- ??
- ????????/** ?
- ?????????*?Load?a?default?resource?loader?definition?if?there?isn't?one?present. ?
- ?????????*?Ben?Hall?(22/08/2003) ?
- ?????????*/ ??
- ????????if ?(p.getProperty(Velocity.RESOURCE_LOADER)?==? null )?{??
- ????????????p.setProperty(Velocity.RESOURCE_LOADER,?"strutsfile,?strutsclass" );??
- ????????}??
?
这里就指明了? velocity.RESOURCE_LOADER 有两个,一个是 stutsfile, 一个是 strutsclass;
?
然后分别指明了 这两个 resource.loader 的详细参数如下:
- p.setProperty( "strutsfile.resource.loader.description" ,? "Velocity?File?Resource?Loader" );??
- ??????????p.setProperty("strutsfile.resource.loader.class" ,? "org.apache.velocity.runtime.resource.loader.FileResourceLoader" );??
- ??????????p.setProperty("strutsfile.resource.loader.path" ,?context.getRealPath( "" ));??
- ??????????p.setProperty("strutsfile.resource.loader.modificationCheckInterval" ,? "2" );??
- ??????????p.setProperty("strutsfile.resource.loader.cache" ,? "true" );??
?
- p.setProperty( "strutsclass.resource.loader.description" ,? "Velocity?Classpath?Resource?Loader" );??
- ??????p.setProperty("strutsclass.resource.loader.class" ,? "org.apache.struts2.views.velocity.StrutsResourceLoader" );??
- ??????p.setProperty("strutsclass.resource.loader.modificationCheckInterval" ,? "2" );??
- ??????p.setProperty("strutsclass.resource.loader.cache" ,? "true" );??
?
于是velocityEngine 引擎在初始化resource.loader 的时候就会初始化这2个loader 了。
?
那么,如果在开发阶段,不希望模板被cache ,能够修改完之后立马看到效果。可以在/WEB-INF/velocity.properties里面加上:
- strutsclass.resource.loader.cache?=? false ??
- ??
- strutsfile.resource.loader.cache?=?false ??
?
============================================================
问题2,struts2 怎么让 velocity 可以支持 layout ?
struts 2 自身带的velocityResult 是不支持 velocity 的layout的,它直接调用的是一个velocityEngine.如果需要它支持的话,需要仿照 velocity-tools中的
VelocityLayoutServlet 来重写 VelocityResult.
?
源代码请看附件
然后在struts.xml中进行配置
- < package ?name= "babystore" ? extends = "struts-default" ? abstract = "true" >??
- ????<result-types>??
- ?????????<result-type?name="velocity" ? class = "com.yajun.babystore.common.struts.VelocityLayoutResult" ? default = "true" />??
- ????</result-types>??
- ???</package >??
- ?????
- <package ?name= "default" ? extends = "babystore" >??
- ????<action?name="HelloWorld" ? class = "helloWorldClass" >??
- ????????<result?name="success" >/success.vm</result>??
- ????</action>??
- ??
- 。。。。。??
?
?
参考: http://www.ibm.com/developerworks/cn/java/j-lo-struts2-velocity/index.html
?
============================================================
?
问题3,struts2 有哪些提供的方便的 tag,如何运用?
struts2 的tag 分为两种:
第一种 Generic Tag :http://struts.apache.org/2.2.1.1/docs/generic-tag-reference.html
第二种 UI Tags :http://struts.apache.org/2.2.1.1/docs/ui-tags.html
?
这些Tag 都是Component的子类如图:
那么这些Component 怎么和velocity ,freemarke 或者其他模板结合的呢? 我这里介绍和velocity结合的方式:
?
先看下图:
?
可以看到在velocity 这个包里面对上面的 component 都有对应的 类支持。
这些类都继承自org.apache.velocity.runtime.directive.Directive?
这个类是用来实现类似velocity 中的 #set 这样的语法的(前面带个#号的那种)
注意到还有个基类:
- public ? abstract ? class ?AbstractDirective? extends ?Directive?{??
- ????public ?String?getName()?{??
- ????????return ? "s" ?+?getBeanName();??
- ????}??
?
发现在每个 beanName 前都加了个字符串s 。这就是为什么 velocity的模板中要用 #surl, #stext, #sform 的原因了。看到这段代码,也就不奇怪了。
?
那么知道了上面的东西之后,想看哪些tag 或者我叫做Component 的是常用的,或者怎么用,就看上面的源码吧。
?
?
问题4,struts2 如何支持 velocity-tools 的 toolbox ?
?
在struts.xml里配置
?
- <constant?name= "struts.velocity.toolboxlocation" ?value= "/WEB-INF/toolbox.xml" ></constant>??
?
然后再WEB-INF/toolbox.xml 下面加上:toolbox.xml
- <? xml ? version = "1.0" ?> ??
- < toolbox > ??
- ????< tool > ??
- ????????< key > link </ key > ??
- ????????< scope > request </ scope > ??
- ????????< class > ??
- ????????????org.apache.velocity.tools.struts.StrutsLinkTool??
- ?????</ class > ??
- ????</ tool > ??
- ????< tool > ??
- ????????< key > msg </ key > ??
- ????????< scope > request </ scope > ??
- ????????< class > ??
- ????????????org.apache.velocity.tools.struts.MessageTool??
- ?????</ class > ??
- ????</ tool > ??
- ????< tool > ??
- ????????< key > errors </ key > ??
- ????????< scope > request </ scope > ??
- ????????< class > ??
- ????????????org.apache.velocity.tools.struts.ErrorsTool??
- ?????</ class > ??
- ????</ tool > ??
- ????< tool > ??
- ????????< key > form </ key > ??
- ????????< scope > request </ scope > ??
- ????????< class > ??
- ????????????org.apache.velocity.tools.struts.FormTool??
- ?????</ class > ??
- ????</ tool > ??
- ????< tool > ??
- ????????< key > tiles </ key > ??
- ????????< scope > request </ scope > ??
- ????????< class > ??
- ????????????org.apache.velocity.tools.struts.TilesTool??
- ?????</ class > ??
- ????</ tool > ??
- ????< tool > ??
- ????????< key > validator </ key > ??
- ????????< scope > request </ scope > ??
- ????????< class > ??
- ????????????org.apache.velocity.tools.struts.ValidatorTool??
- ?????</ class > ??
- ????</ tool > ??
- </ toolbox > ??
?
问题5,struts 与 velocity 整合以后,有哪些内置的变量可以直接用?
- req - the current HttpServletRequest
- res - the current HttpServletResponse
- stack - the current OgnlValueStack
- ognl - an instance of OgnlTool
- ui - a (now deprecated) instance of a ui tag renderer