2
votes

I am new to FreeMarker, and i want to use it to send e-mails. My application has integration of Spring 3.1, Hibernate 3.0 and Struts 2 frameworks.

So, basically my code for sending mail is (i'm using java mail api):

Message message = new MimeMessage(session);

message.setFrom(new InternetAddress(fromAddress));

Address[] addresses = new Address[1];
addresses[0] = new InternetAddress(fromAddress);
message.setReplyTo(addresses);

message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toAddress));
message.setSubject(subject);

//To set template using freemarker

 BodyPart bodyPart = new MimeBodyPart();

 Configuration cfg = new Configuration();
 Template template = cfg.getTemplate("template.ftl");
 Map<String, String> rootMap = new HashMap<String, String>();
 rootMap.put("toName", toName);
 rootMap.put("message", sendMessage);
 Writer out = new StringWriter();
 template.process(rootMap, out);

 bodyPart.setContent(out.toString(), "text/html");

 Multipart multipart = new MimeMultipart();
 multipart.addBodyPart(bodyPart);

 message.setContent(multipart,"text/html; charset=ISO-8859-1");

 Transport.send(message);

But when it tries to send mail,it throws an Exception :

java.io.FileNotFoundException: Template "template.ftl" not found.

The template.ftl file is in WEB-INF/ftl/ directory.

In my spring-config.xml file, i have added this :

<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
    <property name="templateLoaderPath" value="/WEB-INF/ftl/"/>
</bean>

<bean id="viewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
    <property name="cache" value="true"/>
    <property name="prefix" value=""/>
    <property name="suffix" value=".ftl"/>
</bean>
3
can you try to remove the ftl extension when you call getTemplate? - Sergi Almar
Same Exception, Template "template" not found. - Ashish Tanna
when you try to get the template, you should use the configuration that you've defined in the application context, not create a new one - Sergi Almar
As Sergi said, the FreeMarker Configuration that you set up under Spring has nothing to do with the FreeMarker Configuration you create in the Java code. In the last you haven't even set up the TemplateLoader. (Also if you re-create the Configuration for every single mail, it can be quite slow, if you send out a lot of mails. A Configuration instance meant to be singleton.) - ddekany
@SergiAlmar & @ddekany i did that, and its working now. Thanks for your help. :) But, its taking too much time, is it normal? (I have injected the object of FreeMarkerConfigurer to my Email class, and using its getConfiguration method to get the object of Configuration, and then same as above.) - Ashish Tanna

3 Answers

1
votes

Add this statement

cfg.setClassForTemplateLoading(TestTemplate.class, "templates");

before your line

Template template = cfg.getTemplate("template.ftl"); 

Add the template path in the same folder of the method that you will refer to "TestTemplate" for example.

0
votes

You can add setTemplateLoaderPath

@Bean
    public FreeMarkerConfigurer freemarkerConfig() throws IOException, TemplateException {
        FreeMarkerConfigurationFactory factory = new FreeMarkerConfigurationFactory();
        factory.setTemplateLoaderPath("classpath:templates");
        factory.setDefaultEncoding("UTF-8");
        FreeMarkerConfigurer result = new FreeMarkerConfigurer();
        result.setConfiguration(factory.createConfiguration());
        return result;
    }


 final Template template = configuration.getTemplate("file.ftl");
        Map root = new HashMap();
        root.put("user", "Big Joe");
        Writer out = new OutputStreamWriter(System.out);
        template.process(root,out);
0
votes

Suppose that your ftl files are stored under WEB-INF/freemarker, so your spring configuration for freemarkerConfig will be like this:

<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
    <property name="templateLoaderPath" value="/WEB-INF/freemarker/" />
</bean>

In you controller, inject the freemarkerConfig like this:

@Resource(name = "freemarkerConfig")
private FreeMarkerConfigurer freemarkerConfig;

And load your ftl page like this:

Map<String, Object> yourMap = new HashMap<String, Object>();
yourMap.put("var1", "");
yourMap.put("var2", "");
......

String content = FreeMarkerTemplateUtils.processTemplateIntoString(freemarkerConfig.getConfiguration().getTemplate("template.ftl"), yourMap );

The content variable will contain now all your ftl content based on the yourMap Map passed to ftl page, so you can pass it to your api mail.

Check Class FreeMarkerTemplateUtils Documentation for more info about FreeMarkerTemplateUtils.processTemplateIntoString