0

我的 webapp 找不到它的模板文件。我已经阅读了这篇文章中的材料,但似乎并没有解决问题。我的 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)

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

4

1 回答 1

0

你应该使用:

class.resource.loader.class=org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader

资源加载器“类型”在定义加载器类的属性名称之前。

请参阅资源加载器的 Velocity 开发人员指南。请注意,您链接到的答案指向正确的文档,但没有(似乎)包含正确的配置

(说了这么多,您确定这就是您应该使用 VelocityViewServlet 的方式吗?我以为您通常会请求 *.vm 文件,执行类似 a 的fillContext操作,然后完成它。)


Velocity.init()从 VelocityViewServlet 中调用,这很可能不是您想要做的。除此之外,从文档中:

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

于 2013-01-13T02:23:34.067 回答