FreeMarker 模板错误:以下已评估为 null 或缺失 |但不是真的

Posted

技术标签:

【中文标题】FreeMarker 模板错误:以下已评估为 null 或缺失 |但不是真的【英文标题】:FreeMarker template error: The following has evaluated to null or missing | BUT NOT TRUE 【发布时间】:2016-06-18 18:35:21 【问题描述】:

我面临的错误太奇怪了。一切看起来都很好,但是当浏览器向服务器发送 GET 请求时出现此错误。我正在尝试做的实际上是捕获 HTTP 参数,将它们保存在保存在 ArrayList 中的对象中,发送到 Freemarker 模板。

你能帮帮我吗?非常感谢。

错误:

freemarker.log._JULLoggerFactory$JULLogger 错误严重:错误 执行 FreeMarker 模板 FreeMarker 模板报错:以下 已评估为 null 或缺失: ==> item.lat1 [在模板“view/result.ftl”中,第 18 行,第 15 列]

freemarker.core.InvalidReferenceException: [... 异常消息是 已打印;见上面...]在 freemarker.core.InvalidReferenceException.getInstance(InvalidReferenceException.java:131) 在 freemarker.core.EvalUtil.coerceModelToString(EvalUtil.java:355) 在 freemarker.core.Expression.evalAndCoerceToString(Expression.java:82) 在 freemarker.core.DollarVariable.accept(DollarVariable.java:41) 在 freemarker.core.Environment.visit(Environment.java:324) 在 freemarker.core.MixedContent.accept(MixedContent.java:54) 在 freemarker.core.Environment.visitByHiddingParent(Environment.java:345) 在 freemarker.core.IteratorBlock$IterationContext.executeNestedBlockInner(IteratorBlock.java:268) 在 freemarker.core.IteratorBlock$IterationContext.executeNestedBlock(IteratorBlock.java:220) 在 freemarker.core.IteratorBlock$IterationContext.accept(IteratorBlock.java:194) 在 freemarker.core.Environment.visitIteratorBlock(Environment.java:572) 在 freemarker.core.IteratorBlock.acceptWithResult(IteratorBlock.java:78) 在 freemarker.core.IteratorBlock.accept(IteratorBlock.java:64) 在 freemarker.core.Environment.visit(Environment.java:324) 在 freemarker.core.MixedContent.accept(MixedContent.java:54) 在 freemarker.core.Environment.visit(Environment.java:324) 在 freemarker.core.Environment.process(Environment.java:302) 在 freemarker.template.Template.process(Template.java:325) 在 spark.template.freemarker.FreeMarkerEngine.render(FreeMarkerEngine.java:71) 在 controller.App.lambda$main$1(App.java:57) 在 spark.RouteImpl$1.handle(RouteImpl.java:58) 在 spark.webserver.MatcherFilter.doFilter(MatcherFilter.java:162) 在 spark.webserver.JettyHandler.doHandle(JettyHandler.java:61) 在 org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:189) 在 org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) 在 org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:119) 在 org.eclipse.jetty.server.Server.handle(Server.java:517) 在 org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:302) 在 org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:242) 在 org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:245) 在 org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:95) 在 org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:75) 在 org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceAndRun(ExecuteProduceConsume.java:213) 在 org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:147) 在 org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:654) 在 org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:572) 在 java.lang.Thread.run(Thread.java:745)

[qtp285763673-17] 错误 spark.webserver.MatcherFilter - java.lang.IllegalArgumentException: freemarker.core.InvalidReferenceException:以下已评估 为空或丢失: ==> item.lat1 [在模板“view/result.ftl”中,第 18 行,第 15 列]

.. 但确实如此,因为我确实打印了数组并且它工作正常!

  final FreeMarkerEngine freeMarkerEngine = new FreeMarkerEngine();
    final Configuration freeMarkerConfiguration = new Configuration();
    freeMarkerConfiguration.setTemplateLoader(new ClassTemplateLoader(App.class, "/"));
    freeMarkerEngine.setConfiguration(freeMarkerConfiguration);

    get("/rest", (request, response) -> 
        Double lat1 = Double.parseDouble(request.queryParams("lat1") != null ? request.queryParams("lat1") : "anonymous");
        Double lon1 = Double.parseDouble(request.queryParams("lon1") != null ? request.queryParams("lon1") : "anonymous");
        Double lat2 = Double.parseDouble(request.queryParams("lat2") != null ? request.queryParams("lat2") : "anonymous");
        Double lon2 = Double.parseDouble(request.queryParams("lon2") != null ? request.queryParams("lon2") : "anonymous");

        if (shouldReturnhtml(request)) 
            response.status(200);
            response.type("text/html");
            Map<String, Object> attributes = new HashMap<>();
            attributes.put("list",loadTheList(lat1,lon1,lat2,lon2));
            return freeMarkerEngine.render(new ModelAndView(attributes, "/view/result.ftl"));
        
        else 
            response.status(200);
            response.type("application/json");
            return null;
        
    );




private static boolean shouldReturnHtml(Request request) 
    String accept = request.headers("Accept");
    return accept != null && accept.contains("text/html");

public static ArrayList<Bereken> loadTheList(double lat1, double lon1, double lat2, double lon2) 
    ArrayList<Bereken> list = new ArrayList<>();
    list.add(new Bereken(lat1,lon1,lat2,lon2));
    return list;

还有result.ftl:

      <#list list as item>
        <h2>$item.lat1</h2>
        <h2>$item.lon1</h2>
        <h2>$item.lat2</h2>
        <h2>$item.lon2</h2>
    </#list>

【问题讨论】:

【参考方案1】:

我知道这是一个老问题,但我只是碰到了这个问题。如果您将私有类的实例(我刚刚尝试过)传递给 Freemarker,它还会抱怨该值“为空或缺失”。如果你传入一个 Java Bean 类,它需要public。在这种情况下,错误消息非常具有误导性。

【讨论】:

你是对的,我用 private inner class 测试了它,只有 getter 方法。它不工作;但后来我将内部类更改为public,它现在可以工作了。谢谢!【参考方案2】:

您正在将 Bereken 类的 1 个实例添加到“列表”中。 所以我会假设 Bereken 类不提供公共属性 lat1、lat2、lon1、lon2 或对应的 getter 方法。

【讨论】:

【参考方案3】:

我昨天刚碰到这个。我正在完成一个教程,其中一个步骤不包括创建对象的类中的 getter 方法的代码。我猜作者只是假设读者知道这应该已经发生了。

因此,无论这个“Bereken”是什么(我刚刚了解到它是一个 JavaBean 类),请务必为与“列表”中的每个元素关联的属性添加 setter 和 getter 方法。

【讨论】:

以上是关于FreeMarker 模板错误:以下已评估为 null 或缺失 |但不是真的的主要内容,如果未能解决你的问题,请参考以下文章

执行 FreeMarker 时,以下已评估为 null 或缺失

Freemarker 模板错误

FreeMarker:需要一个哈希,但这已经评估为一个序列

freemarker.core.InvalidReferenceException: [... Exception message was already printed; see it above

如何使用 Freemarker 模板输出 JSON

在Freemarker模板中检查Spring安全角色和已记录的用户名