以速度查找模板文件

时间:2013-01-13 02:16:02

标签: java web-applications velocity

我的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)

有人可以向我解释发生了什么事吗?感谢。

1 个答案:

答案 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下找到配置文件,但对我来说,至少,它不是。