SeamFramework.orgCommunity Documentation
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 38.2.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.org/schema/seam/mail"
xmlns:h="http://java.sun.com/jsf/html">
<m:from name="Peter" address="peter@example.com" />
<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.
Whilst most mail readers nowadays support HTML, some don't, so you can add a plain text alternative to your email body:
<m:body>
<f:facet name="alternative">Sorry, your email reader can't show our fancy email,
please go to http://labs.jboss.com/jbossseam to explore Seam.</f:facet>
</m:body>
Often you'll want to send an email to a group of recipients (for
example your users). All of the recipient mail tags can be placed
inside a <ui:repeat>
:
<ui:repeat value="#{allUsers} var="user">
<m:to name="#{user.firstname} #{user.lastname}" address="#{user.emailAddress}" />
</ui:repeat>
Sometimes, however, you need to send a slightly different message to
each recipient (e.g. a password reset). The best way to do this is to
place the whole message inside a <ui:repeat>
:
<ui:repeat value="#{people}" var="p">
<m:message>
<m:from name="#{person.firstname} #{person.lastname}">#{person.address}</m:from>
<m:to name="#{p.firstname}">#{p.address}</m:to>
...
</m:message>
</ui:repeat>
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="do-not-reply@jboss.com" />
<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 asynchronously
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!
Seam supports sending internationalised messages. By default, the encoding provided by JSF is used, but this can be overridden on the template:
<m:message charset="UTF-8">
...
</m:message>
The body, subject and recipient (and from) name will be encoded. You'll need to make sure facelets uses the correct charset for parsing your pages by setting encoding of the template:
<?xml version="1.0" encoding="UTF-8"?>
Sometimes you'll want to add other headers to your email. Seam provides support for some (see Section 22.4, “Tags”). For example, we can set the importance of the email, and ask for a read receipt:
<m:message xmlns:m="http://jboss.org/schema/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 4.x 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.
JBoss AS 5.x and newer has mail-ra.rar applied the patches, so there is no need to copy the mail-ra.rar from Seam distribution.
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
must not 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 Seam Mail module requires the use of Facelets as the view technology. This is the default View technology in JSF 2. Additionally, it requires the use of the jboss-seam-ui module.
The mailSession
component uses JavaMail to talk to a
'real' SMTP server.
A JavaMail Session may be available via a JNDI lookup if you are working in an JEE environment or you can use a Seam configured Session.
The mailSession component's properties are described in more detail in Section 33.9, “Mail-related components”.
The JBoss AS 7 Mail service is defined in standalone/configuration/standalone.xml
file. It configures a
JavaMail session binding into JNDI. The default service
configuration will need altering for your network.
Full article how to configure Mail system in JBoss AS 7
describes the service in more detail.
<components xmlns="http://jboss.org/schema/seam/components"
xmlns:core="http://jboss.org/schema/seam/core"
xmlns:mail="http://jboss.org/schema/seam/mail">
<mail:mail-session session-jndi-name="java:jboss/mail/Default"/>
</components>
Here we tell Seam to get the mail session bound to
java:jboss/mail/Default
from JNDI.
A mail session can be configured via components.xml
.
Here we tell Seam to use smtp.example.com
as the
smtp server:
<components xmlns="http://jboss.org/schema/seam/components"
xmlns:core="http://jboss.org/schema/seam/core"
xmlns:mail="http://jboss.org/schema/seam/mail">
<mail:mail-session host="smtp.example.com"/>
</components>
Emails are generated using tags in the http://jboss.org/schema/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
.
Root tag of a mail message
importance
— low, normal or high. By
default normal, this sets the importance of the mail message.
precedence
— sets the precedence of
the message (e.g. bulk).
requestReadReceipt
— by default false,
if set, a read receipt request will be will be added, with the
read receipt being sent to the From:
address.
urlBase
— If set, the value is
prepended to the requestContextPath
allowing
you to use components such as
<h:graphicImage>
in your emails.
messageId
— Sets the Message-ID explicitly
Set's the From: address for the email. You can only have one of these per email.
name
— the name the email should come
from.
address
— the email address the email
should come from.
Set's the Reply-to: address for the email. You can only have one of these per email.
address
— the email address the email
should come from.
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>.
name
— the name of the recipient.
address
— the email address of the recipient.
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>.
name
— the name of the recipient.
address
— the email address of the
recipient.
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>.
name
— the name of the recipient.
address
— the email address of the
recipient.
Add a header to the email (e.g. X-Sent-From: JBoss Seam
)
name
— The name of the header to
add (e.g. X-Sent-From
).
value
— The value of the header to
add (e.g. JBoss Seam
).
Add an attachment to the email.
value
— The file to attach:
String
— A String
is interpreted as a path to file within the classpath
java.io.File
— An EL expression
can reference a File
object
java.net.URL
— An EL expression
can reference a URL
object
java.io.InputStream
— An EL
expression can reference an InputStream
.
In this case both a fileName
and a
contentType
must be specified.
byte[]
— An EL expression can
reference an byte[]
. In this case both
a fileName
and a
contentType
must be specified.
If the value attribute is ommitted:
If this tag contains a <p:document>
tag, the document described will be generated and
attached to the email. A fileName
should be specified.
If this tag contains other JSF tags a HTML document will
be generated from them and attached to the email. A
fileName
should be specified.
fileName
— Specify the file name to
use for the attached file.
contentType
— Specify the MIME type
of the attached file
Set's the subject for the email.
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.
type
— If set to plain
then a plain text email will be generated otherwise an HTML
email is generated.