| > Home |
Using JSP for Email Templates in Struts |
![]() |
How can I use JSP for Email Templates? is a question that comes up on the Struts User List at fairly frequent intervals. The answer often given is to use Velocity Template Engine which provides a solution for templating that is not tied to the Servlet Specification. Thats a good solution but if, for whatever reason, you still want a JSP solution rather than Velocity then this page describes a simple approach to templating using JSP's.
Another alternative, put forward by Chris McCormack is to use the Jakarta Taglibs Mailer taglib.
Create your JSP email template and use the Struts <bean:define> tag to store the generated content in a request scope attribute.
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
<bean:define id="emailStuff" toScope="request">
<html>
<body>
<h1><bean:write name="emailHeading"/></h1>
<p><bean:write name="emailBody"/></p>
</body>
</html>
</bean:define>
|
Use a RequestDispatcher to generate the email from the template.
public class TemplateAction extends Action {
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
// Set up attributes used by the template
request.setAttribute("emailHeading", "Test Heading");
request.setAttribute("emailBody", "This is some body text");
// Generate the email
String emailTemplateJSP = "/WEB-INF/jsp/EmailTestTemplate.jsp";
RequestDispatcher rd = servlet.getServletContext().getRequestDispatcher(emailTemplateJSP);
rd.include(request, response);
// Get the generated email from the request attribute
String emailStuff = (String)request.getAttribute("emailStuff");
// ...send the email
// forward to appropriate page
return mapping.findForward("success");
}
}
|
N.B. The emailStuff attribute is the scripting variable that the <bean:define> tag was told to store its body content under in the JSP.
This section includes feedback posted on the Struts User list to the above solution.
3.1 Kris Schneider posted the following feedback:
For the paranoid, you probably want to be sure that the email template ("EmailTestTemplate.jsp") doesn't actually produce any output. Because you're doing an include followed by a forward, there's a *possibility* that the forward will throw an IllegalStateException if the include causes the response to be committed. You can use one of the various JSP whitespace "hacks" to help:
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %><bean:define id="emailStuff" toScope="request"> ... </bean:define> |
Obviously, the example is unlikely to cause a problem, but a more involved page might.
Another approach might be to pass an HttpServletResponseWrapper to the include method whose output stream (or writer) just buffers the entire response for later retrieval.
3.2 Kishore Senji suggested increasing the buffer size to avoid the issue raised by Kris Schneider above:
<%@ page buffer="10kb" autoFlush="false" %><%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %><bean:define id="emailStuff" toScope="request"> ... </bean:define> |
He also suggests.... if you define your action to extend IncludeAction, then by having the path to template in the "parameter" you could have the call to RequestDispatcher delegated to IncludeAction like so :
public class TemplateAction extends IncludeAction {
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
// Set up attributes used by the template
request.setAttribute("emailHeading", "Test Heading");
request.setAttribute("emailBody", "This is some body text");
// Generate the email
super.execute(mapping, form, request, response);
// Get the generated email from the request attribute
String emailStuff = (String)request.getAttribute("emailStuff");
// ...send the email
// forward to appropriate page
return mapping.findForward("success");
}
}
|
Note: Don't forget if you use Kishore's IncludeAction suggestion you need to set the parameter in the struts-config.xml
to the path of the email template (i.e. /WEB-INF/jsp/EmailTestTemplate.jsp in this example).