Reputation: 20956
Despite there are a lot of discussion around freemarker + spring but it is hard to find neat working example to copy and run.
Could you please provide simplest working configuration of freemarker in spring xml context and java code snippet to load template from resource file and process it.
Upvotes: 13
Views: 25046
Reputation: 20956
pom.xml
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
</dependency>
applicationContext.xml
<bean id="freeMarkerConfigurationFactory" class="org.springframework.ui.freemarker.FreeMarkerConfigurationFactoryBean">
<property name="templateLoaderPath" value="classpath:/META-INF/freemarker"/>
<property name="preferFileSystemAccess" value="false"/>
</bean>
AlertMailComposer.java
import static org.springframework.ui.freemarker.FreeMarkerTemplateUtils.processTemplateIntoString;
@Component
public class AlertMailComposer implements Processor {
public static final String TEMPLATE = "AlertMail.ftl";
@Autowired
private Configuration freemarkerConfiguration;
protected String composeHtml(Alert alert) throws IOException, TemplateException {
return processTemplateIntoString(freemarkerConfiguration.getTemplate(TEMPLATE), ImmutableMap.of(
"alertType", alert.getAlertType(),
"message", alert.getMessage(),
"nodeName", alert.getEvent().getNodeName(),
"event", toJson(alert.getEvent(), true)
));
}
...
AlertMail.ftl
<html>
<body style="font-family:verdana;font-size:10">
<b>${alertType}: </b>${message}<br>
<b>on: </b>${nodeName}<br>
<p/>
<pre style="font-family:verdana;font-size:10;color:grey">
${event}
</pre>
</body>
</html>
Configuration
class has some interesting properties, like ClassForTemplateLoading
to load resources relative to some class or using basePackagePath. Similar to Class.getResource
.
@Autowired
private FreeMarkerConfigurationFactory freeMarkerConfigurationFactory;
@Bean
public freemarker.template.Configuration negativeRatesFreeMarkerConfiguration() throws IOException, TemplateException {
freemarker.template.Configuration configuration = freeMarkerConfigurationFactory.createConfiguration();
configuration.setClassForTemplateLoading(getClass(), "/" + getClass().getPackage().getName().replace('.', '/'));
return configuration;
}
...
@Resource(name = "negativeRatesFreeMarkerConfiguration")
private Configuration freemarkerConfiguration;
...
freemarkerConfiguration.getTemplate("/service/emailReport.ftl")
Upvotes: 25
Reputation: 68905
Other than maven dependency in pom.xml to use it with java configuration in spring you can do -
public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] { MyRootContextConfig.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { MyServletContextConfig.class };
}
@Override
protected String[] getServletMappings() {
return new String[] { "/test/*" };
}
}
and then MyRootContextConfig
can have
@Bean(name = "myFreeMarkerConfigruation")
public FreeMarkerConfigurationFactoryBean getFreeMarkerConfiguration() {
FreeMarkerConfigurationFactoryBean bean = new FreeMarkerConfigurationFactoryBean();
bean.setTemplateLoaderPath("classpath:/templates/");
return bean;
}
Upvotes: 0
Reputation: 63
In the spring context xml, declaring FreemarkerConfigurationFactoryBean
is sufficient, i.e.
<bean id="freemarkerConfigFactory" class="org.springframework.ui.freemarker.FreeMarkerConfigurationFactoryBean">
<property name="templateLoaderPath" value="classpath:templates/"/>
</bean>
No need to further specify freemarker.template.Configuration
bean in the xml file if you use @Autowired
annotation. It is created by the factory and injected by Spring.
Upvotes: 4