1

为什么速度为字符串提供以下输出

VelocityContext vc = new VelocityContext();
vc.put("foo", "bar");
String inString = "THis is ${{foo}} and this is ${foo}.Hello and ${foo}-Hello";

StringWriter sw = new StringWriter();
ve.evaluate(vc, sw, "Tag", inString);

输出:

THis is ${{} and this is bar.Hello and bar-Hello 

我期待它会打印${{foo}}或者{bar},为什么${{}?双卷曲会充当转义字符吗?

我在设置为 true 的严格参考模式下使用它。而且我既没有看到异常,也没有看到它按原样打印,这让我感到困惑。

4

2 回答 2

0

好吧,您让我查看了代码,但我不确定我是否理解正确。问题似乎是在 ${...} 中,xxx 被视为 ASTReference,然后它的标记化方式与独立字符串“{bar}”不同。具体来说,它被标记为 3 个标记 {、bar 和 }。然后引擎试图找到引用的所谓根(在 ${x} 中,根是 x),无法识别模式并进入后备引用类型 RUNT,它表示第一个标记,即“ {”很重要。这样“{bar}”就变成了“{”。

换句话说,表达式 ${{bar}} 没有意义,Velocity 无法在此处抛出错误。在其他无意义的组​​合中,例如 ${[bar]} 它实际上会引发错误。

于 2017-11-04T15:28:48.593 回答
0

速度变量VTL Identifier

必须以字母字符开头(a .. z 或 A .. Z)。其余字符仅限于以下类型的字符:

  • 字母(a .. z,A .. Z)
  • 数字 (0 .. 9)
  • 连字符(“-”)
  • 下划线(“_”)

您正在使用正式引用符号作为 ${varName}

${{foo}}- 所以速度尝试获取无效的 VTL 标识符的变量 {foo},因此它不会尝试加载变量。

然后它可能会尝试将其引用为 JSON 映射 {"a":"b"} 并再次失败,可能仅{被接受,因此您仍然保留:

${ {}

我在新速度 2.0 中测试了你的模板,这个问题没有重现(在严格或非严格模式下)输出:

THis is ${{foo}} and this is bar.Hello and bar-Hello 

所以你现在有理由升级到velocity 2.0了。

于 2017-11-01T11:56:06.487 回答