Created
October 9, 2012 14:12
-
-
Save moravcik/3859062 to your computer and use it in GitHub Desktop.
Freemarker template example with Spring expressions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<@spel expression="We say '{@greetingBean.printGreeting(name)}'"/> from Freemarker |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<dependency> | |
<groupId>org.freemarker</groupId> | |
<artifactId>freemarker</artifactId> | |
<version>2.3.19</version> | |
</dependency> | |
<dependency> | |
<groupId>javax.servlet</groupId> | |
<artifactId>servlet-api</artifactId> | |
<version>2.5</version> | |
<scope>provided</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework</groupId> | |
<artifactId>spring-webmvc</artifactId> | |
<version>3.1.2.RELEASE</version> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework</groupId> | |
<artifactId>spring-test</artifactId> | |
<version>3.1.2.RELEASE</version> | |
<scope>test</scope> | |
</dependency> | |
<dependency> | |
<groupId>com.adaptiweb.utils</groupId> | |
<artifactId>spel-evaluator</artifactId> | |
<version>1.5-SNAPSHOT</version> | |
</dependency> | |
<dependency> | |
<groupId>junit</groupId> | |
<artifactId>junit</artifactId> | |
<version>4.8.2</version> | |
<scope>test</scope> | |
</dependency> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class SpelFreemarkerTemplateDirective implements TemplateDirectiveModel { | |
SpelEvaluator spelEvaluator; | |
@Required | |
public void setSpelEvaluator(SpelEvaluator spelEvaluator) { | |
this.spelEvaluator = spelEvaluator; | |
} | |
@Override | |
public void execute(Environment env, @SuppressWarnings("rawtypes") Map params, TemplateModel[] loopVars, | |
TemplateDirectiveBody body) throws TemplateException, IOException { | |
@SuppressWarnings("unchecked") | |
String spelResult = spelEvaluator | |
// set all freemarker variables as root object - map | |
.setRootObject(new FreemarkerVariables(env, env.getKnownVariableNames())) | |
// resolve expression either from parameter or from body | |
.setExpression(resolveSpelExpression(params, body)) | |
.evaluate(String.class); | |
env.getOut().write(spelResult); | |
spelEvaluator.dispose(); | |
} | |
private String resolveSpelExpression(Map<String, Object> params, TemplateDirectiveBody body) throws TemplateException, IOException { | |
if (params.containsKey("expression")) { | |
TemplateModel expressionModel = (TemplateModel) params.get("expression"); | |
return (String) DeepUnwrap.permissiveUnwrap(expressionModel); | |
} else { // expression in body | |
StringWriter expressionWriter = new StringWriter(); | |
body.render(expressionWriter); | |
return expressionWriter.toString(); | |
} | |
} | |
static class FreemarkerVariables implements Map<String, Object> { | |
final Environment env; | |
final Set<String> variableNames; | |
FreemarkerVariables(Environment env, Set<String> variableNames) { | |
this.env = env; | |
this.variableNames = variableNames; | |
} | |
@Override | |
public int size() { | |
return variableNames.size(); | |
} | |
@Override | |
public boolean isEmpty() { | |
return variableNames.isEmpty(); | |
} | |
@Override | |
public boolean containsKey(Object key) { | |
return variableNames.contains(key); | |
} | |
@Override | |
public Object get(Object key) { | |
try { | |
TemplateModel model = env.getVariable((String) key); | |
return DeepUnwrap.permissiveUnwrap(model); | |
} catch (TemplateModelException e) { | |
return null; | |
} | |
} | |
@Override | |
public Set<String> keySet() { | |
return variableNames; | |
} | |
@Override public boolean containsValue(Object value) { throw new RuntimeException("Unsupported operation"); } | |
@Override public Object put(String key, Object value) { throw new RuntimeException("Unsupported operation"); } | |
@Override public Object remove(Object key) { throw new RuntimeException("Unsupported operation"); } | |
@Override public void putAll(Map<? extends String, ? extends Object> m) { throw new RuntimeException("Unsupported operation"); } | |
@Override public void clear() { throw new RuntimeException("Unsupported operation"); } | |
@Override public Collection<Object> values() { throw new RuntimeException("Unsupported operation"); } | |
@Override public Set<java.util.Map.Entry<String, Object>> entrySet() { throw new RuntimeException("Unsupported operation"); } | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<beans xmlns="http://www.springframework.org/schema/beans" | |
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xmlns:p="http://www.springframework.org/schema/p" | |
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> | |
<!-- FreeMarker configuration --> | |
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer" | |
p:configuration-ref="freemarkerConfiguration"/> | |
<bean id="freemarkerConfiguration" class="org.springframework.ui.freemarker.FreeMarkerConfigurationFactoryBean" | |
p:templateLoaderPath="/" p:preferFileSystemAccess="false"> | |
<property name="freemarkerVariables"> | |
<map> | |
<entry key="spel" value-ref="spelDirective"/> | |
</map> | |
</property> | |
</bean> | |
<bean id="spelDirective" class="com.adaptiweb.blog.example.SpelFreemarkerTemplateDirective" | |
p:spelEvaluator-ref="spelEvaluator"/> | |
<bean id="spelEvaluator" class="com.adaptiweb.utils.spel.SpelEvaluatorFactoryBean" | |
p:useBeanResolver="true" p:useBeanAccessor="true" p:useMapAccessor="true" | |
p:templatePrefix="{" p:templateSuffix="}"/> | |
<bean id="greetingBean" class="com.adaptiweb.blog.example.SpelFreemarkerTest.GreetingBean" | |
p:greeting="Hello"/> | |
</beans> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@RunWith(SpringJUnit4ClassRunner.class) | |
@ContextConfiguration | |
public class SpelFreemarkerTest { | |
@Autowired GreetingBean greetingBean; | |
@Autowired Configuration freemarkerConfig; | |
@Test | |
public void testFreemarkerSpel() throws IOException, TemplateException { | |
Map<String, String> model = new HashMap<String, String>(); | |
model.put("name", "Felix"); | |
Template template = freemarkerConfig.getTemplate("greeting-template.ftl"); | |
String output = FreeMarkerTemplateUtils.processTemplateIntoString(template, model); | |
System.out.println(output); | |
String expected = "We say '" + greetingBean.printGreeting(model.get("name")) + "' from Freemarker"; | |
assertEquals(expected, output); | |
} | |
public static class GreetingBean { | |
private String greeting; | |
@Required | |
public void setGreeting(String greeting) { | |
this.greeting = greeting; | |
} | |
public String printGreeting(String name) { | |
return greeting + " " + name; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment