velocity 实现嵌套变量解析
velocity Implementing nested variable resolution
我想通过velocity生成controller层代码。
我生成一个映射方法:
@ResponseBody
@PostMapping(value = "\${peacetrue.${moduleName}.urls.add}")
public ${ModuleName}VO add(${ModuleName}Add params) {
logger.info("add record[{}]", params);
return ${moduleName}Service.add(params);
}
然后我遇到异常:
{DomainName}Controller.java.vm[line 18, column 39]
Was expecting one of:
"[" ...
"|" ...
"}" ...
"}" ...
然后我写了一个单元测试:
@Test
public void translate() {
Velocity.init();
Map<String, Object> singletonMap = Collections.singletonMap("foo", "bar");
StringWriter stringWriter = new StringWriter();
Velocity.evaluate(new VelocityContext(singletonMap), stringWriter, "log", "$foo");
Assert.assertEquals("bar", stringWriter.toString());
stringWriter = new StringWriter();
Velocity.evaluate(new VelocityContext(singletonMap), stringWriter, "log", "\${com.${foo}.name}");
Assert.assertEquals("${com.bar.name}", stringWriter.toString());
}
那我该怎么办?
您可以像这样使用 #evaluate()
指令(至少从 v1.7 开始):
@PostMapping("#evaluate("$peacetrue.${moduleName}.urls.add")")
或(对于以前的版本)像这样:
@PostMapping("#set($d='$')#evaluate("${d}peacetrue.${moduleName}.urls.add")")
或者如果 EscapeTool 出现在上下文中:
@PostMapping("#evaluate("${esc.dollar}peacetrue.${moduleName}.urls.add")")
或者如果 $peacetrue
有标准的 getter 模块(像 .getFoo()
或 get('foo')
作为地图):
@PostMapping("$peacetrue.get($moduleName).urls.add")
可以用implementation 'org.apache.velocity.tools:velocity-tools-generic:3.0'
实现
@Test
public void translate() {
VelocityEngine engine = new VelocityEngine();
engine.init();
Map<String, Object> singletonMap = Collections.singletonMap("foo", "bar");
StringWriter stringWriter = new StringWriter();
Velocity.evaluate(new VelocityContext(singletonMap), stringWriter, "log", "$foo");
Assert.assertEquals("bar", stringWriter.toString());
stringWriter = new StringWriter();
ToolManager manager = new ToolManager(true, true);
manager.setVelocityEngine(engine);
manager.configure(getEasyFactoryConfiguration());
ToolContext context = manager.createContext();
context.put("foo","bar");
Velocity.evaluate(context, stringWriter, "log", "${esc.d}{com.${foo}.name}");
Assert.assertEquals("${com.bar.name}", stringWriter.toString());
}
private EasyFactoryConfiguration getEasyFactoryConfiguration() {
EasyFactoryConfiguration config = new EasyFactoryConfiguration();
config.toolbox("application").tool(EscapeTool.class);
return config;
}
我想通过velocity生成controller层代码。 我生成一个映射方法:
@ResponseBody
@PostMapping(value = "\${peacetrue.${moduleName}.urls.add}")
public ${ModuleName}VO add(${ModuleName}Add params) {
logger.info("add record[{}]", params);
return ${moduleName}Service.add(params);
}
然后我遇到异常:
{DomainName}Controller.java.vm[line 18, column 39]
Was expecting one of:
"[" ...
"|" ...
"}" ...
"}" ...
然后我写了一个单元测试:
@Test
public void translate() {
Velocity.init();
Map<String, Object> singletonMap = Collections.singletonMap("foo", "bar");
StringWriter stringWriter = new StringWriter();
Velocity.evaluate(new VelocityContext(singletonMap), stringWriter, "log", "$foo");
Assert.assertEquals("bar", stringWriter.toString());
stringWriter = new StringWriter();
Velocity.evaluate(new VelocityContext(singletonMap), stringWriter, "log", "\${com.${foo}.name}");
Assert.assertEquals("${com.bar.name}", stringWriter.toString());
}
那我该怎么办?
您可以像这样使用 #evaluate()
指令(至少从 v1.7 开始):
@PostMapping("#evaluate("$peacetrue.${moduleName}.urls.add")")
或(对于以前的版本)像这样:
@PostMapping("#set($d='$')#evaluate("${d}peacetrue.${moduleName}.urls.add")")
或者如果 EscapeTool 出现在上下文中:
@PostMapping("#evaluate("${esc.dollar}peacetrue.${moduleName}.urls.add")")
或者如果 $peacetrue
有标准的 getter 模块(像 .getFoo()
或 get('foo')
作为地图):
@PostMapping("$peacetrue.get($moduleName).urls.add")
可以用implementation 'org.apache.velocity.tools:velocity-tools-generic:3.0'
@Test
public void translate() {
VelocityEngine engine = new VelocityEngine();
engine.init();
Map<String, Object> singletonMap = Collections.singletonMap("foo", "bar");
StringWriter stringWriter = new StringWriter();
Velocity.evaluate(new VelocityContext(singletonMap), stringWriter, "log", "$foo");
Assert.assertEquals("bar", stringWriter.toString());
stringWriter = new StringWriter();
ToolManager manager = new ToolManager(true, true);
manager.setVelocityEngine(engine);
manager.configure(getEasyFactoryConfiguration());
ToolContext context = manager.createContext();
context.put("foo","bar");
Velocity.evaluate(context, stringWriter, "log", "${esc.d}{com.${foo}.name}");
Assert.assertEquals("${com.bar.name}", stringWriter.toString());
}
private EasyFactoryConfiguration getEasyFactoryConfiguration() {
EasyFactoryConfiguration config = new EasyFactoryConfiguration();
config.toolbox("application").tool(EscapeTool.class);
return config;
}