我的webapp无法找到其模板文件。我已经阅读了this article中的资料,但它似乎没有解决问题。我的velocity.properties文件安装在我的WEB-INF目录中,包含行
resource.loader=class
resource.loader.class=org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
,Java servlet是
package test;
import java.io.*;
import javax.servlet.http.*;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.context.Context;
import org.apache.velocity.tools.view.VelocityViewServlet;
import org.apache.velocity.app.Velocity;
import org.apache.commons.lang.StringEscapeUtils;
public class Recipes extends VelocityViewServlet {
public Template handleRequest(HttpServletRequest request,
HttpServletResponse response,
Context context) {
Velocity.init();
Template template=null;
try {
context.put("recipeList","r1");
template = Velocity.getTemplate("Recipes.vm");
} catch (Exception e) {
System.err.println("Exception caught: " + e.getMessage());
}
return template;
}
}
当我导航到该URL时,它会失败。我已经尝试将vm文件放在WEB-INF目录,classes子目录,lib目录和lib目录中的jar中。事情失败后,catalina.out包含
Jan 12, 2013 6:35:25 PM org.apache.velocity.runtime.log.CommonsLogLogChute log
SEVERE: ResourceManager : unable to find resource 'Recipes.vm' in any resource loader.
Exception caught: Unable to find resource 'Recipes.vm'
并在localhost.log
中Jan 12, 2013 6:35:25 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet recipes threw exception
java.lang.NullPointerException
at org.apache.velocity.tools.view.VelocityView.performMerge(VelocityView.java:942)
at org.apache.velocity.tools.view.VelocityView.merge(VelocityView.java:902)
at org.apache.velocity.tools.view.VelocityViewServlet.mergeTemplate(VelocityViewServlet.java:318)
at org.apache.velocity.tools.view.VelocityViewServlet.doRequest(VelocityViewServlet.java:220)
at org.apache.velocity.tools.view.VelocityViewServlet.doGet(VelocityViewServlet.java:182)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:619)
有人可以向我解释发生了什么事吗?感谢。
答案 0 :(得分:0)
您应该使用:
class.resource.loader.class=org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
资源加载器“type”位于定义加载器类的属性名称之前。
See the Velocity Developer Guide to Resource Loaders。请注意,您链接的答案指向正确的文档,但没有(显示)包含正确的配置
(所有这些都说,你确定你应该如何使用VelocityViewServlet吗?我认为你通常会请求* .vm文件,执行类似fillContext
的操作,并完成它。)
您正在从VelocityViewServlet中调用Velocity.init()
,这很可能不是您想要做的。除此之外,来自文档:
使用Velocity分布的默认属性
初始化Velocity运行时引擎
如果您执行以下操作,我显示的配置有效:
String propFile = getServletContext().getRealPath("/WEB-INF/velocity.properties");
Velocity.init(propFile);
那就是说,我不相信你会以正确的方式解决这个问题,但我可能会误会 - 我之前从未在独立的网络应用程序中使用它,但这并没有让我觉得正确的。
如果不出意外,我至少会将一些东西移到基类中,比如:
public abstract class BaseVelocityServlet extends VelocityViewServlet {
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
Velocity.init(getServletContext().getRealPath("/WEB-INF/velocity.properties"));
}
@Override
protected Template getTemplate(HttpServletRequest request, HttpServletResponse response) {
return Velocity.getTemplate(getTemplateName());
}
public abstract String getTemplateName();
}
然后每个URL的servlet都可以填充上下文并提供模板名称:
public class Recipes extends BaseVelocityServlet {
@Override
protected void fillContext(Context context, HttpServletRequest request) {
context.put("recipeList", "r1");
}
@Override
public String getTemplateName() {
return "Recipes.vm";
}
}
同样,我不相信这是对的;我仍然认为它应该是默认情况下在WEB-INF下找到配置文件,但对我来说,至少,它不是。