Velocity与Struts 1.* -- VM展示

本文介绍如何在Struts1.*版本中使用Velocity模板引擎显示数据。通过配置VelocityViewServlet处理.vm模板文件,实现ActionForward跳转到Velocity模板并正确显示数据。
在Struts中有两种使用Velocity的方法,一种是利用Velocity的vm模板进行页面展示,一种则是利用Velocity来生成静态页面。以下介绍在Struts 1.*版本中使用Velocity的vm模板显示。

在Struts 1.*版本中,并未支持对vm模板的显示,所以当ActionForward指向一个vm模板时,只会将模板中的Velocit语句当做普通字符内容显示出来,而不对其中的Velocity语句进行任何解析及赋值。所以在Struts 1.*版本中使用Velocity,需要在web.xml中配置VelocityViewServlet,以处理后缀为.vm的模板文件。

在web.xml中进行如下配置:
<servlet>
<servlet-name>velocity</servlet-name>
<servlet-class>
org.apache.velocity.tools.view.servlet.VelocityViewServlet
</servlet-class>
<init-param>
<param-name>org.apache.velocity.toolbox</param-name>
<param-value>/WEB-INF/toolbox.xml</param-value>
</init-param>
<load-on-startup>10</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>velocity</servlet-name>
<url-pattern>*.vm</url-pattern>
</servlet-mapping>

这样当ActionForward指向一个后缀为vm的模板时,该Servlet便会进行对vm模板的解析及赋值工作。
在web.xml中配置Struts 1.2的ActionServlet步骤省略。

vm模板:namelist.vm
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>StrutsSample_1</title>
</head>
<body>
<h3>StrutsSample</h3>
<table width="400" border="1">
#foreach($name in $list)
<tr> <td>$name</td> </tr>
#end
</table>
</body>
</html>


Struts Action
public class StrutsSample extends DispatchAction {
public ActionForward showNameList(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
ActionForward forward = new ActionForward();
ActionMessages errors = new ActionMessages();
List<String> list = new ArrayList<String>();
String name = null;
for(int i=0;i<20;i++){
name = "Hoffman "+i+" Name";
list.add(name);
}
request.setAttribute("list", list);
if (!errors.isEmpty()) {
saveErrors(request, errors);
forward = new ActionForward(mapping.getInput());
} else {
forward = new ActionForward("/namelist.vm");
}
return forward;
}
}

[color=blue]这里需要注意forward = new ActionForward("/namelist.vm");这句,因为在velocity.properties中已经配置了模板存放位置,所以这里直接可以指定模板名称。需要注意的是这里和Servlet中应用不同,Servlet是通过getTemplate("sample.vm")来获取模板,而Struts则是通过转发,所以模板前需要加上/。关于在servlet中使用velocity,请参考本博客的《[url=http://schiz.iteye.com/blog/677097]Velocity简单示例源码解析[/url]》一文)[/color]

Struts配置
<struts-config>
<action-mappings>
<action path="/StrutsSample" parameter="dispatch" scope="request"
type="com.mixele.velocity.struts.StrutsSample" validate="true">
<forward name="namelist" path="/templates/namelist.vm" redirect="false"/>
</action>
</action-mappings>
</struts-config>


浏览器输入:http://localhost:8080/Mixele_Velocity/StrutsSample.do?dispatch=showNameList
便可看到处理结果。

在Struts的Action中,只做了对用户请求的处理,以及回复工作,和vm模板解析相关的所有工作,由VelocityViewServlet完成。
在web.xml中配置VelocityViewServlet后,当系统启动时,VelocityViewServlet类会初始化。

VelocityViewServlet初始化过程
public void init(ServletConfig config) throws ServletException {
super.init(config);
initVelocity(config); //初始化Velocity
initToolbox(config); //初始化Servlet的toolbox
//当Velocity初始化后,可以获取以下这些(默认内容类型、模板字符编码)
defaultContentType = RuntimeSingleton.getString(CONTENT_TYPE, DEFAULT_CONTENT_TYPE);
String encoding = RuntimeSingleton.getString(
RuntimeSingleton.OUTPUT_ENCODING, DEFAULT_OUTPUT_ENCODING);
if (!DEFAULT_OUTPUT_ENCODING.equalsIgnoreCase(encoding)) {
int index = defaultContentType.lastIndexOf("charset");
if (index < 0) {
defaultContentType += "; charset=" + encoding;
} else {
Velocity.warn("VelocityViewServlet: Charset was already "
+ "specified in the Content-Type property. "
+ "Output encoding property will be ignored.");
}
}
Velocity.info("VelocityViewServlet: Default content-type is: " + defaultContentType);
}

/** 初始化Velocity */
protected void initVelocity(ServletConfig config) throws ServletException {
Velocity.setApplicationAttribute(SERVLET_CONTEXT_KEY, getServletContext());
// default to servletlogger, which logs to the servlet engines log
Velocity.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS,
ServletLogger.class.getName());
// by default, load resources with webapp resource loader
Velocity.setProperty(RuntimeConstants.RESOURCE_LOADER, "webapp");
Velocity.setProperty("webapp.resource.loader.class", WebappLoader.class.getName());
// Try reading an overriding Velocity configuration
try {
ExtendedProperties p = loadConfiguration(config); //读取配置文件(velocity.properties)
Velocity.setExtendedProperties(p);
} catch (Exception e) {
……源码省略……
}
try {
Velocity.init(); //now all is ready - init Velocity
} catch (Exception e) {
getServletContext().log(
"VelocityViewServlet: PANIC! unable to init() - " + e);
throw new ServletException(e);
}
}

/** 读取Velocity配置文件velocity.properties中的配置
* 若该文件不存在,使用默认配置,即org/apache/velocity/tools/view/servlet/velocity.properties */
protected ExtendedProperties loadConfiguration(ServletConfig config) throws IOException {
ServletContext servletContext = config.getServletContext();
//获取Velocity文件的路径
String propsFile = config.getInitParameter(INIT_PROPS_KEY);
if (propsFile == null || propsFile.length() == 0) {
propsFile = servletContext.getInitParameter(INIT_PROPS_KEY);
}
ExtendedProperties p = new ExtendedProperties();
if (propsFile != null) {
p.load(servletContext.getResourceAsStream(propsFile));
Velocity.info("VelocityViewServlet: Custom Properties File: " + propsFile);
} else {
Velocity.info("VelocityViewServlet: No custom properties found. "
+ "Using default Velocity configuration.");
}
return p;
}

/** 读取Velocity Tools配置文件toolbox.xml中的配置
* 若该文件不存在,使用Velocity Tools的默认配置 */
protected void initToolbox(ServletConfig config) throws ServletException {
ServletContext servletContext = config.getServletContext();
/* 检查Servlet配置中关于toolbox的配置(即/WEB-INF/toolbox.xml) */
String file = config.getInitParameter(TOOLBOX_KEY);
System.out.println("VelocityViewServlet == initToolbox == file = "+file);
/* check the servlet context for a toolbox */
if (file == null || file.length() == 0) {
file = servletContext.getInitParameter(TOOLBOX_KEY);
}
/* if we have a toolbox, get a manager for it */
if (file != null) {
toolboxManager = ServletToolboxManager.getInstance(servletContext, file);
} else {
Velocity.info("VelocityViewServlet: No toolbox entry in configuration.");
}
}

和在Servlet中使用Velocity一样,只是在初始化的过程中增加了读取Velocity Tools配置文件的步骤。
当Action跳转打到VM文件时,VelocityViewServlet类会对VM类型文件进行解析和赋值处理。
过程如下:
doGet() --> doRequest() --> createContext() --> setContentType() --> handleRequest() --> getTemplate() --> mergeTemplate() --> getResponseWriter() --> requestCleanup()

doGet():复写的HttpServlet方法,以获取用户的request
doRequest():这是处理vm的主要方法,在其中调用了以下方法:
createContext() – 获取Velocity的上下文
setContentType() – 设置HttpServletResponse的内容类型
handleRequest() – 使用模板处理请求(这个方法通过模板路径返回一个模板对象)
mergeTemplate() – 将模板和嵌入模板中的值合并
requestCleanup() – 应该是资源回收的方法,不过源码里是个空方法
通过以上的方法,VelocityViewServlet类对vm的解析赋值完成。
【事件触发一致性】研究多智能体网络如何通过分布式事件驱动控制实现有限时间内的共识(Matlab代码实现)内容概要:本文围绕多智能体网络中的事件触发一致性问题,研究如何通过分布式事件驱动控制实现有限时间内的共识,并提供了相应的Matlab代码实现方案。文中探讨了事件触发机制在降低通信负担、提升系统效率方面的优势,重点分析了多智能体系统在有限时间收敛的一致性控制策略,涉及系统模型构建、触发条件设计、稳定性收敛性分析等核心技术环节。此外,文档还展示了该技术在航空航天、电力系统、机器人协同、无人机编队等多个前沿领域的潜在应用,体现了其跨学科的研究价值和工程实用性。; 适合人群:具备一定控制理论基础和Matlab编程能力的研究生、科研人员及从事自动化、智能系统、多智能体协同控制等相关领域的工程技术人员。; 使用场景及目标:①用于理解和实现多智能体系统在有限时间内达成一致的分布式控制方法;②为事件触发控制、分布式优化、协同控制等课题提供算法设计仿真验证的技术参考;③支撑科研项目开发、学术论文复现及工程原型系统搭建; 阅读建议:建议结合文中提供的Matlab代码进行实践操作,重点关注事件触发条件的设计逻辑系统收敛性证明之间的关系,同时可延伸至其他应用场景进行二次开发性能优化。
【四旋翼无人机】具备螺旋桨倾斜机构的全驱动四旋翼无人机:建模控制研究(Matlab代码、Simulink仿真实现)内容概要:本文围绕具备螺旋桨倾斜机构的全驱动四旋翼无人机展开,重点研究其动力学建模控制系统设计。通过Matlab代码Simulink仿真实现,详细阐述了该类无人机的运动学动力学模型构建过程,分析了螺旋桨倾斜机构如何提升无人机的全向机动能力姿态控制性能,并设计相应的控制策略以实现稳定飞行精确轨迹跟踪。文中涵盖了从系统建模、控制器设计到仿真验证的完整流程,突出了全驱动结构相较于传统四旋翼在欠驱动问题上的优势。; 适合人群:具备一定控制理论基础和Matlab/Simulink使用经验的自动化、航空航天及相关专业的研究生、科研人员或无人机开发工程师。; 使用场景及目标:①学习全驱动四旋翼无人机的动力学建模方法;②掌握基于Matlab/Simulink的无人机控制系统设计仿真技术;③深入理解螺旋桨倾斜机构对飞行性能的影响及其控制实现;④为相关课题研究或工程开发提供可复现的技术参考代码支持。; 阅读建议:建议读者结合提供的Matlab代码Simulink模型,逐步跟进文档中的建模控制设计步骤,动手实践仿真过程,以加深对全驱动无人机控制原理的理解,并可根据实际需求对模型控制器进行修改优化。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值