SeamFramework.orgCommunity Documentation

Chapter 21. Email

21.1. Creating a message
21.1.1. Attachments
21.1.2. HTML/Text alternative part
21.1.3. Multiple recipients
21.1.4. Multiple messages
21.1.5. Templating
21.1.6. Internationalisation
21.1.7. Other Headers
21.2. Receiving emails
21.3. Configuration
21.3.1. mailSession
21.4. Meldware
21.5. Tags

Seam now includes an optional components for templating and sending emails.

Email support is provided by jboss-seam-mail.jar. This JAR contains the mail JSF controls, which are used to construct emails, and the mailSession manager component.

The examples/mail project contains an example of the email support in action. It demonstrates proper packaging, and it contains a number of example that demonstrate the key features currently supported.

You can also test your mail's using Seam's integration testing environment. See Section 37.3.4, “Integration Testing Seam Mail”.

You don't need to learn a whole new templating language to use Seam Mail — an email is just facelet!


<m:message xmlns="http://www.w3.org/1999/xhtml"
    xmlns:m="http://jboss.com/products/seam/mail"
    xmlns:h="http://java.sun.com/jsf/html">
  
    <m:from name="Peter" address="
[email protected]" />
    <m:to name="#{person.firstname} #{person.lastname}">#{person.address}</m:to>
    <m:subject>Try out Seam!</m:subject>
    
    <m:body>
        <p><h:outputText value="Dear #{person.firstname}" />,</p>
        <p>You can try out Seam by visiting 
        <a href="http://labs.jboss.com/jbossseam">http://labs.jboss.com/jbossseam</a>.</p>
        <p>Regards,</p>
        <p>Pete</p>
    </m:body>
    
</m:message>

The <m:message> tag wraps the whole message, and tells Seam to start rendering an email. Inside the <m:message> tag we use an <m:from> tag to set who the message is from, a <m:to> tag to specify a sender (notice how we use EL as we would in a normal facelet), and a <m:subject> tag.

The <m:body> tag wraps the body of the email. You can use regular HTML tags inside the body as well as JSF components.

So, now you have your email template, how do you go about sending it? Well, at the end of rendering the m:message the mailSession is called to send the email, so all you have to do is ask Seam to render the view:

@In(create=true)

private Renderer renderer;
   
public void send() {
    try {
       renderer.render("/simple.xhtml");
       facesMessages.add("Email sent successfully");
   } 
   catch (Exception e) {
       facesMessages.add("Email sending failed: " + e.getMessage());
   }
}

If, for example, you entered an invalid email address, then an exception would be thrown, which is caught and then displayed to the user.

Seam makes it easy to attach files to an email. It supports most of the standard java types used when working with files.

If you wanted to email the jboss-seam-mail.jar:


<m:attachment value="/WEB-INF/lib/jboss-seam-mail.jar"/>

Seam will load the file from the classpath, and attach it to the email. By default it would be attached as jboss-seam-mail.jar; if you wanted it to have another name you would just add the fileName attribute:


<m:attachment value="/WEB-INF/lib/jboss-seam-mail.jar" fileName="this-is-so-cool.jar"/>

You could also attach a java.io.File, a java.net.URL:


<m:attachment value="#{numbers}"/>

Or a byte[] or a java.io.InputStream:


<m:attachment value="#{person.photo}" contentType="image/png"/>

You'll notice that for a byte[] and a java.io.InputStream you need to specify the MIME type of the attachment (as that information is not carried as part of the file).

And it gets even better, you can attach a Seam generated PDF, or any standard JSF view, just by wrapping a <m:attachment> around the normal tags you would use:


<m:attachment fileName="tiny.pdf">
    <p:document>                                                      
        A very tiny PDF                                                                                                
    </p:document>
</m:attachment>

If you had a set of files you wanted to attach (for example a set of pictures loaded from a database) you can just use a <ui:repeat>:


<ui:repeat value="#{people}" var="person">
    <m:attachment value="#{person.photo}" contentType="image/jpeg" fileName="#{person.firstname}_#{person.lastname}.jpg"/>
</ui:repeat>

And if you want to display an attached image inline:


<m:attachment 
    value="#{person.photo}" 
    contentType="image/jpeg" 
    fileName="#{person.firstname}_#{person.lastname}.jpg" 
    status="personPhoto" 
    disposition="inline" />
<img src="cid:#{personPhoto.contentId}" />

You may be wondering what cid:#{...} does. Well, the IETF specified that by putting this as the src for your image, the attachments will be looked at when trying to locate the image (the Content-ID's must match) — magic!

You must declare the attachment before trying to access the status object.

The mail templating example shows that facelets templating just works with the Seam mail tags.

Our template.xhtml contains:


<m:message>
   <m:from name="Seam" address="
[email protected]" />
   <m:to name="#{person.firstname} #{person.lastname}">#{person.address}</m:to>
   <m:subject>#{subject}</m:subject>
   <m:body>
       <html>
           <body>
               <ui:insert name="body">This is the default body, specified by the template.</ui:insert>
           </body>
       </html>
   </m:body>
</m:message>

Our templating.xhtml contains:


<ui:param name="subject" value="Templating with Seam Mail"/>
<ui:define name="body">
    <p>This example demonstrates that you can easily use <i>facelets templating</i> in email!</p>
</ui:define>

You can also use facelets source tags in your email, but you must place them in a jar in WEB-INF/lib - referencing the .taglib.xml from web.xml isn't reliable when using Seam Mail (if you send your mail asynchrounously Seam Mail doesn't have access to the full JSF or Servlet context, and so doesn't know about web.xml configuration parameters).

If you do need more configure Facelets or JSF when sending mail, you'll need to override the Renderer component and do the configuration programmatically - only for advanced users!

Sometimes you'll want to add other headers to your email. Seam provides support for some (see Section 21.5, “Tags”). For example, we can set the importance of the email, and ask for a read receipt:


<m:message xmlns:m="http://jboss.com/products/seam/mail"
    importance="low"
    requestReadReceipt="true"/>

Otherwise you can add any header to the message using the <m:header> tag:


<m:header name="X-Sent-From" value="JBoss Seam"/>

If you are using EJB then you can use a MDB (Message Driven Bean) to receive email. JBoss provides a JCA adaptor — mail-ra.rar — but the version distributed with JBoss AS has a number of limitations (and isn't bundled in some versions) therefore we recommend using the mail-ra.rar distributed with Seam (it's in the extras/ directory in the Seam bundle). mail-ra.rar should be placed in $JBOSS_HOME/server/default/deploy; if the version of JBoss AS you use already has this file, replace it.

You can configure it like this:

@MessageDriven(activationConfig={

    @ActivationConfigProperty(propertyName="mailServer", propertyValue="localhost"),
    @ActivationConfigProperty(propertyName="mailFolder", propertyValue="INBOX"),
    @ActivationConfigProperty(propertyName="storeProtocol", propertyValue="pop3"),
    @ActivationConfigProperty(propertyName="userName", propertyValue="seam"),
    @ActivationConfigProperty(propertyName="password", propertyValue="seam")
})
@ResourceAdapter("mail-ra.rar")
@Name("mailListener")
public class MailListenerMDB implements MailListener {
    @In(create=true)
    private OrderProcessor orderProcessor;
    public void onMessage(Message message) {
       // Process the message
       orderProcessor.process(message.getSubject());
    }
   
}

Each message received will cause onMessage(Message message) to be called. Most Seam annotations will work inside a MDB but you musn't access the persistence context.

You can find more information on mail-ra.rar at http://www.jboss.org/community/wiki/InboundJavaMail.

If you aren't using JBoss AS you can still use mail-ra.rar or you may find your application server includes a similar adapter.

To include Email support in your application, include jboss-seam-mail.jar in your WEB-INF/lib directory. If you are using JBoss AS there is no further configuration needed to use Seam's email support. Otherwise you need to make sure you have the JavaMail API, an implementation of the JavaMail API present (the API and impl used in JBoss AS are distributed with seam as lib/mail.jar), and a copy of the Java Activation Framework (distributed with Seam as lib/activation.jar.

The mailSession component uses JavaMail to talk to a 'real' SMTP server.

Seam's mail examples use Meldware (from buni.org) as a mail server. Meldware is a groupware package that provides SMTP, POP3, IMAP, webmail, a shared calendar and an graphical admin tool; it's written as a JEE application so can be deployed onto JBoss AS alongside your Seam application.

Caution

The version of Meldware distributed with Seam (downloaded on demand) is specially tailored for development - mailboxes, users and aliases (email addresses) are created every time the application deploys. If you want to use Meldware in production you should install the latest release from buni.org.

Emails are generated using tags in the http://jboss.com/products/seam/mail namespace. Documents should always have the message tag at the root of the message. The message tag prepares Seam to generate an email.

The standard templating tags of facelets can be used as normal. Inside the body you can use any JSF tag; if it requires access to external resources (stylesheets, javascript) then be sure to set the urlBase.

<m:message>

Root tag of a mail message

<m:from>

Set's the From: address for the email. You can only have one of these per email.

<m:replyTo>

Set's the Reply-to: address for the email. You can only have one of these per email.

<m:to>

Add a recipient to the email. Use multiple <m:to> tags for multiple recipients. This tag can be safely placed inside a repeat tag such as <ui:repeat>.

<m:cc>

Add a cc recipient to the email. Use multiple <m:cc> tags for multiple ccs. This tag can be safely placed inside a iterator tag such as <ui:repeat>.

<m:bcc>

Add a bcc recipient to the email. Use multiple <m:bcc> tags for multiple bccs. This tag can be safely placed inside a repeat tag such as <ui:repeat>.

<m:header>

Add a header to the email (e.g. X-Sent-From: JBoss Seam)

<m:attachment>

Add an attachment to the email.

<m:subject>

Set's the subject for the email.

<m:body>

Set's the body for the email. Supports an alternative facet which, if an HTML email is generated can contain alternative text for a mail reader which doesn't support html.