更好的模板语言需求

8

是的,我知道this 已经 问过 。但大多数问题都是两年前的,现在一定有更好的答案。

我需要一个用于呈现HTML的模板语言。要求如下:

  1. 必须能够从Java中调用。

  2. 不能使用Freemarker、Velocity或StringTemplate。我们使用Freemarker已经一年了,但它太慢了。在负载下,它消耗了我们50%的CPU周期。Velocity比Freemarker还要糟糕,而StringTemplate也有自己的问题。

  3. 它必须能够处理JSON或其Java等效物,即Maps、Lists和primitives。

我开始对Node.js产生嫉妒了。在过去的一年里,JavaScript模板活动非常活跃,但Java方面却很少(就我所知)。
理想的语言应该看起来像Liquid,但它只适用于Rails。 Jade适用于Java,但我不想要它带来的所有HTML重新格式化。 更新 最终我选择了Handlebars,它也可以用于Java。两者都很好用。

问题陈述中已经带有争议性,这怎么能是建设性的呢? - Don Roby
你能详细说明一下为什么你认为Velocity比Freemarker更糟糕吗?我从未遇到过这样的系统消耗问题。 - Claude Brisson
你可以使用SpEL(Spring Expression Language)。它快速,稳定,并且具有比Velocity或Freemarker更现代的运算符。 - Mohsen
你们有使用缓存吗?我们将不经常更改的内容生成的HTML进行缓存,并将非常动态(例如用户会话)的内容设置为非缓存。这可能有助于解决您的CPU问题。 - geekonablog
2
我必须同意ddekany(和Claude)的观点。我接触Freemarker和Velocity已经多年了,从未听说过50%的CPU使用率。很有可能是你做错了什么。也许要检查一下你的循环。 - Nathan Bubna
显示剩余3条评论
2个回答

4

Chunk是友好的json。在您的控制器代码或模板中,可以将JSON用作标记值以进行exec / macro调用。

{% exec %}
  {% data @json %}
    { name: "whatever",
      vitals: ["an","array","of","data"],
      friends: [{name: "bob"},{name: "crystal"}]
    }
  {% enddata %}

  <div>Name: {$name}</div>

  {% if ($friends) %}
    <div>Friends:

      <ul>
      {% loop in $friends as $friend %}
        <li>{$friend.name}</li>
      {% endloop %}
      </ul>

    </div>
  {% endif %}

{% endexec %}

或者,只需使用内部模板并从Java端注入JSON。

src/themes/example.chtml

  <div>Name: {$name}</div>

  {% if ($friends) %}
  <div>Friends:

    <ul>
    {% loop in $friends as $friend %}
     <li>{$friend.name}</li>
    {% endloop %}
    </ul>

  </div>
  {% endif %}

MyController.java

Theme theme = new Theme();
Chunk html = theme.makeChunk("example");

html.set("name", "whatever");
html.set("vitals", getJsonArray() );
html.set("friends", getJsonFriendObjects() );

html.render( out );

只要getJsonXXX()方法返回实现List和Map的内容,Chunk就可以正确地将其粘合到模板中(即使这些列表和映射嵌套更多的列表和映射)。
<div>Name: whatever</div>

<div>Friends:

  <ul>
   <li>bob</li>
   <li>crystal</li>
  </ul>

</div>

Chunk 是最棒的伙计们! - dns

0

Java+是一个简单的预处理器解决方案。它只是将标记字符串化:

System.out.println({{
 <html>
  <body>
   ...
  </body>
</html>}})

它具有可配置的分隔符,并通过Java代码而不是消耗它来传递:

System.out.println({{
<xmlExample>
  <name>{{fpp}}</name>
  <number>{{bar}}</number>
</xmlExample>
}});

参考资料


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接