【问题标题】:Finding template files in velocity在速度中查找模板文件
【发布时间】:2013-01-13 02:16:02
【问题描述】:

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

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

【问题讨论】:

    标签: java web-applications velocity


    【解决方案1】:

    你应该使用:

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

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

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

    【讨论】:

    • 所以,这并没有解决问题。我仍然得到完全相同的错误。
    • @rogerl 你用的是什么版本的东西? (引擎、工具等)
    • jar 是velocity-1.7.jar、velocity-tools-generic-2.0.jar 和velocity-tools-view-2.0.jar。
    • 本地主机日志文件还包含消息 Velocity [debug] 无法从资源加载器 org.apache.velocity.runtime.resource.loader.ClassspathResourceLoader 加载资源“VM_global_library.vm”:ClasspathResourceLoader 错误:不能查找资源 VM_global_library.vm。
    • @rogerl 因为您在调用Velocity.init() 时没有提供属性文件名的路径。查看更新的答案。
    猜你喜欢
    • 2011-02-25
    • 1970-01-01
    • 1970-01-01
    • 2020-09-30
    • 1970-01-01
    • 1970-01-01
    • 2022-08-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多