Java 在另一个In-Spring应用程序中包含Velocity模板
我可能想做一些不寻常的事。我有一个SpringWeb应用程序,我正在手动呈现一个velocity模板,这意味着调用Java 在另一个In-Spring应用程序中包含Velocity模板,java,spring,templates,velocity,Java,Spring,Templates,Velocity,我可能想做一些不寻常的事。我有一个SpringWeb应用程序,我正在手动呈现一个velocity模板,这意味着调用 template.merge(context, stringWriter) 以下是我如何从应用程序中获取模板: InputStream inputStream = servletContext.getResourceAsStream("/WEB-INF/vml/" + templateName); String templateString = StreamUtils.input
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\u ROOT
,我也没有使用Velocity类路径资源加载程序
所以我的问题是,我的选择是什么?基本目标是能够手动呈现这些模板,并且能够在另一个模板中包含一个模板,所有这些都在SpringWeb应用程序中
我已尝试通过使用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:找不到资源'/vml/hello.vml'
。我被困在这里,因为这耗尽了我所知道的获取模板的两种方法 以下是
尝试将模板放入WEB-INF/lib目录。出于测试目的,尽量不要创建任何类似vml的子目录,这样当某些东西仍然无法工作时,您就不会感到困惑。Velocity配置不是Spring中最好的文档部分。而且它已经过时了:即使在4.0.5中,参考文档也声明了对velocity 1.x(fine)和velocity工具(1.x)的依赖关系,这在velocity的最新版本中已被弃用。尽管如此,只要配置了velocity 1.7和velocity tools 2.0,所有工具都可以正常工作
允许velocity在WEB-INF下查找模板的部分是velocity工具的WebappResourceLoader
。一旦您的VelocityEngine
被声明使用它来加载模板,所有这些都可以正常工作,包括在其他模板中包含模板
因此,您可以继续以速度方式进行配置。准备速度特性,包括:
resource.loader=webapp
webapp.resource.loader.class=org.apache.velocity.tools.view.WebappResourceLoader
webapp.resource.loader.path=/WEB-INF/vml
并初始化并正常使用VelocityEngine
但您也可以使用SpringVelocityConfigure
,如果您以后想在应用程序(*)中使用velocity视图,这将非常有用。以下是工作应用程序上下文的摘录:
<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"/>
(*)VelocityLayoutViewResolver
在该环境中正常工作,但为了能够使用2.0 velocity工具箱,我必须修改默认的SpringVelocityLayoutView
并在resolver中声明我的子类:
在dispatcher 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">
...
我认为其中一个棘手的问题是WEB-INF被分解并部署到一个自定义位置/usr/share/jboss-5.1.0.GA/server/myServlet/deploy/dev.ear/dev.war/WEB-INF/lib/hello.vml
当我打印文件时,我仍然会得到org.apache.velocity.exception.resourcennotfoundexception:找不到资源'/hello.vml'
通过URL[]URL=((URLClassLoader)cl.geturl()指向记录器的类路径;对于(URL-URL:URL){LOGGER.info(“类路径项:+URL.getFile());}
,我看到了类路径项:/usr/share/jboss-5.1.0.GA/bin/run.jar
,因为模板不在类路径中,而是直接在WEB-INF下(这对于WEB应用程序来说很正常),您不能使用ClasspathResourceLoader
。那么我的选项是什么?换句话说,如果没有任何velocity初始化的加载程序,我如何将一个模板包含在另一个模板中?或者我必须使用类加载器还是url加载器?我认为通过velocity初始化是可能的。如何初始化速度引擎
?它是春豆吗?或者您使用的velocity单例模型只使用velocity
类?它目前不是Springbean,尽管我并不反对尝试这种方法。目前,它的初始化方式如上所述,使用“private static VelocityEngine VelocityEngine=new VelocityEngine();静态{velocityEngine.setProperty(RuntimeConstants.RESOURCE_LOADER,“classpath”);velocityEngine.setProperty(“classpath.RESOURCE.LOADER.class”,ClasspathResourceLoader.class.getName());velocityEngine.init();}`是的,靠Greyskull的力量!那就行了!谢谢,先生。接下来,我注意到$contextVariable并没有在包含的模板中被解释,而是作为文本字符串“$contextVariable”出现。这些包含的模板中是否没有上下文?我如何做到这一点?我的foreach循环等也被逐字呈现,例如#foreach($foo in$傻瓜)#end
就是这样出现的。我该怎么办?velocityEngine似乎没有将这些Include识别为velocity模板。也许我需要这样配置它。@davidwillams:在velocity中,#include
只包含修复文本。您必须使用#parse
来包含另一个模板。
<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">
...
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());
}
}