我可能正在尝试做一些不寻常的事情。我有一个 Spring Web 应用程序,我正在手动渲染速度模板,这意味着调用
template.merge(context, stringWriter)
以下是我从应用程序获取模板的方法:
InputStream inputStream = servletContext.getResourceAsStream("/WEB-INF/vml/" + templateName);
String templateString = StreamUtils.inputStreamToString(inputStream);
RuntimeServices runtimeServices = RuntimeSingleton.getRuntimeServices();
StringReader reader = new StringReader(templateString);
SimpleNode node = runtimeServices.parse(reader, templateName);
Template template = new Template();
template.setRuntimeServices(runtimeServices);
template.setData(node);
template.initDocument();
我相信我必须以这种方式加载模板,因为我没有使用 Spring 的 VelocityViewResolver
将模板呈现为请求的一部分(这是 Jboss 中后台任务的一部分)。但现在我当然无法在这个模板中包含模板,因为Velocity不知道从哪里获取它们,而且我还没有设置TEMPLATE_ROOT
我也没有使用 Velocity ClasspathResourceLoader。
所以我的问题是,我有什么选择?基本目标是能够手动渲染这些模板,并能够将一个模板包含在另一个模板中,所有这些都在 Spring Web 应用程序中进行。
我尝试通过使用 ClasspathResourceLoader
static {
velocityEngine.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
velocityEngine.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
velocityEngine.init();
}
我在 WEB-INF/vml/hello.vml
下放置了一个小的 hello world 模板。当我尝试调用velocityEngine.getTemplate("/vml/hello.vml");
时无论 vml 之前有或没有前导正斜杠,我都会得到 org.apache.velocity.exception.ResourceNotFoundException: Unable to find resource '/vml/hello.vml'
。我被困在这里,因为这用尽了我所知道的获取模板的两种方法。
最佳答案
速度配置并不是 Spring 中记录最好的部分。而且它已经相当过时了:即使在 4.0.5 中,引用文档也声明了对velocity 1.x(fine)和velocity-tools(1.x)的依赖,这在最新版本的velocity 中已被弃用。尽管如此,一旦配置了速度 1.7 和速度工具 2.0,一切都可以正常工作
允许velocity在WEB-INF下找到模板的部分是velocity-tools的WebappResourceLoader
。一旦您的 VelocityEngine
被声明为使用它来加载模板,一切都会正常工作,包括模板包含在其他模板中。
因此您可以继续以速度方式进行配置。您准备的速度属性包括:
resource.loader=webapp
webapp.resource.loader.class=org.apache.velocity.tools.view.WebappResourceLoader
webapp.resource.loader.path=/WEB-INF/vml
并初始化并正常使用VelocityEngine
但是您也可以使用 Spring VelocityConfigurer
,如果您以后想在应用程序中使用速度 View (*),它可能会很有用。以下是工作应用程序上下文的摘录:
<bean id="velocityConfig" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
<property name="resourceLoaderPath" value="/WEB-INF/velocity/"/>
<property name="velocityProperties">
<props>
<prop key="input.encoding">UTF-8</prop>
<prop key="output.encoding">UTF-8</prop>
<prop key="velocimacro.library">VM_global_library.vm</prop>
<prop key="resource.loader">webapp</prop>
<prop key="webapp.resource.loader.class">org.apache.velocity.tools.view.WebappResourceLoader</prop>
<prop key="webapp.resource.loader.path">/WEB-INF/vlm</prop>
<prop key="evaluate.provide.scope.control">true</prop>
</props>
</property>
</bean>
<bean id="velocityEngine" factory-bean="velocityConfig" factory-method="getVelocityEngine"/>
你会得到一个完全配置的VelocityEngine
,Spring可以在你需要的任何bean中注入(inject)它(我认为property name="resourceLoaderPath"
是一个scory在旧版本上,但由于它有效,我不敢删除它,并且 VM_global_library.vm
是我自己的速度宏库,位于 webapp.resource.loader.path
下,可从我的所有模板访问)。我目前使用此配置来生成邮件正文。
不,您有速度引擎(直接配置或通过 VelocityConfigurer
配置),您可以使用它来加载和合并模板:
Template template = velocityEngine.getTemplate("/hello.vml");
Context context = new VelocityContext();
context.put(..., ...);
...
template.merge(context, writer);
(*) VelocityLayoutViewResolver
在该环境中可以正常工作,但为了能够使用 2.0 速度工具箱,我必须修改默认的 Spring VelocityLayoutView
并声明我的子类在解析器中:
在调度程序 servlet 中:
<bean class="org.springframework.web.servlet.view.velocity.VelocityLayoutViewResolver"
id="vmViewResolver" p:order="10" p:suffix=".vm" p:prefix=""
p:cache="true" p:contentType="text/html;charset=UTF-8"
p:exposeRequestAttributes="false" p:exposeSessionAttributes="false"
p:exposePathVariables="true" p:exposeSpringMacroHelpers="true"
p:dateToolAttribute="date" p:toolboxConfigLocation="/WEB-INF/toolbox.xml"
p:viewClass="i2.application.commun.web.views.Velocity2LayoutView">
...
和我的Velocity2LayoutView
public class Velocity2LayoutView extends VelocityLayoutView {
ViewToolManager toolManager;
@Override
protected Context createVelocityContext(Map<String, Object> model,
HttpServletRequest request, HttpServletResponse response) throws Exception {
ViewToolContext context = toolManager.createContext(request, response);
context.putAll(model);
return context;
}
@Override
protected void initTool(Object tool, Context velocityContext) throws Exception {
//super.initTool(tool, velocityContext);
}
@Override
public void afterPropertiesSet() throws Exception {
toolManager = new ViewToolManager(getServletContext(), false, false);
if (getToolboxConfigLocation() != null) {
String path = getToolboxConfigLocation();
logger.debug("Init ViewToolManager with " + path);
XmlFactoryConfiguration config = new XmlFactoryConfiguration();
config.read(getServletContext().getResourceAsStream(getToolboxConfigLocation()));
toolManager.configure(config);
}
toolManager.setVelocityEngine(getVelocityEngine());
}
}
关于java - 在 Spring 应用程序中的另一个中包含 Velocity 模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24441100/