Seam现在包含了一个用于模板和发送邮件的可选组件。
邮件支持是由 jboss-seam-mail.jar 提供的。 这个JAR包包括用于创建邮件的mail JSF控件,以及 mailSession 管理组件。
examples/mail项目包括一份实用的email支持示例。该例子示范了恰当的打包方式,并且包含了一些当前支持的关键特性。
你也可以使用Seam的集成测试环境来测试你的mail程序,参见 Section 31.3.2, “Seam Mail集成测试”。
为了使用Seam Mail,你并不需要完整的学习一门模板语言—一封邮件仅仅是一个facelet!【Facelet是用来建立JSF应用程序时的一个可供选择的表现层技术】
<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>
<m:message> 标签包装整个消息,并且通知Seam开始渲染一封邮件。 在这个 <m:message> 标签内,我们使用标签 <m:from> 来设置这个消息是来自谁, 使用标签 <m:to> 来标识发送者(注意我们就和在普通的facelet里一样使用EL),和 <m:subject> 标签。
<m:body> 标签包装邮件的主体。你可以像JSF组件那样将正规的HTML标签用在邮件主体内。
好,现在你已经有了email的模板,你将如何发送它呢? 在 m:message 的结尾,mailSession 将被调用,用于发送邮件。 所以,你所有要做的仅仅是请求Seam渲染这个视图:
@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()); } }
假如:你输入了一个无效的email地址,将会抛出一个异常。该异常将被捕捉并显示给用户。
Seam中邮件添加附件的操作变得轻而易举。在处理文件时,它支持绝大多数的标准Java类型。
如果你想通过邮件发送 jboss-seam-mail.jar:
<m:attachment value="/WEB-INF/lib/jboss-seam-mail.jar"/>
Seam将通过classpath加载文件,并将其附件加入到到邮件中。 默认情况下,它将被像 jboss-seam-mail.jar 一样加载; 如果你想为它添加别名,只需要添加 fileName 属性即可。
<m:attachment value="/WEB-INF/lib/jboss-seam-mail.jar" fileName="this-is-so-cool.jar"/>
你同样可以附加 java.io.File、java.net.URL:
<m:attachment value="#{numbers}"/>
也可以是 byte[] 或是 java.io.InputStream:
<m:attachment value="#{person.photo}" contentType="image/png"/>
你会注意到对于 byte[] 和 java.io.InputStream, 你需要指定附件的MIME类型(因为这两种文件不带此类信息。)
更好的是,你可以附Seam产生的PDF或任意标准的JSF视图,只需将你使用的普通标签用 <m:attachment> 封装起来即可:
<m:attachment fileName="tiny.pdf"> <p:document> A very tiny PDF </p:document> </m:attachment>
如果你想将多个文件添加到附件中(例如从数据库加载的一套照片),你只需要使用 <ui:repeat>:
<ui:repeat value="#{people}" var="person"> <m:attachment value="#{person.photo}" contentType="image/jpeg" fileName="#{person.firstname}_#{person.lastname}.jpg"/> </ui:repeat>
如果你想直接显示一个附上的图片:
<m:attachment value="#{person.photo}" contentType="image/jpeg" fileName="#{person.firstname}_#{person.lastname}.jpg" status="personPhoto" disposition="inline" /> <img src="cid:#{personPhoto.contentId}" />
你可能会问 cid:#{...} 的作用是什么。 是这样的,IETF明确规定将这个标签加入作为你图片的src(源文件),当试着定位图片(Content-ID必须匹配)时,它就能够被查找到。— 多么神奇!
在访问状态对象之前你必须声明附件。
尽管现在绝大多数的邮件查看器都支持HTML格式的邮件,但还是有一些不支持,所以你可以在邮件体里添加一个无格式的文本作为替换。
<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>
很多时候你希望向一个收件组(比如你的用户们)发送邮件。 所有的收件人标签可以被放在一个 <ui:repeat> 标签中:
<ui:repeat value="#{allUsers} var="user"> <m:to name="#{user.firstname} #{user.lastname}" address="#{user.emailAddress}" /> </ui:repeat>
有时候,你需要向每一个收件人发送一条稍微有差别的信(例如:重设密码)。 最好的方法就是将整个信息放在 <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>
邮件模板示例显示(facelets模板)可以和Seam的mail标签很好的结合。
我们的 template.xhtml 包括:
<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>
我们的 templating.xhtml 包括:
<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>
你也可以在你的邮件中使用facelet的源标签,但你必须将它们置于一个jar包中并放在 WEB-INF/lib 目录下 - 当使用Seam Mail从 web.xml 引用 .taglib.xml 并不可靠。 (因为如果你异步的发送你的邮件,Seam Mail无法访问到完整的JSF或Servlet上下文,所以并不知道 web.xml 的配置参数)
发送邮件时,如果你需要更多的配置Facelets或JSF,你需要重载Renderer组件,并且编程式地做配置工作 - 仅限于高级用户。
Seam支持发送国际化的信息。默认情况下,使用JSF提供的编码,但也可以由如下的模板重写:
<m:message charset="UTF-8"> ... </m:message>
邮件内容、主题和收件人(和发件人)的名称都会被编码。通过设置模板的编码,你需要确认facelets是否使用了正确的编码方式来解析你的页面。
<?xml version="1.0" encoding="UTF-8"?>
有时候你会想在邮件上添加其他的头信息。Seam提供了一部分支持(请看 Section 17.5, “标签”)。 例如:我们可以设置邮件的重要程度,或着请求一个阅读回执。
<m:message xmlns:m="http://jboss.com/products/seam/mail" importance="low" requestReadReceipt="true"/>
另外你也可以通过使用 <m:header> 标签,为消息添加其它任意的头信息。
<m:header name="X-Sent-From" value="JBoss Seam"/>
如果你正在使用EJB,你可以使用MDB(消息驱动Bean:Message Driven Bean)来接收消息。 JBoss提供JCA适配器 —mail-ra.rar 但是跟随JBoss发布的版本有一定的限制(某些版本没有做捆绑)。 因此我们建议采用跟随推荐的Seam发布的 mail-ra.rar(不在Seam包的 mail 目录)。 mail-ra.rar 应该被放置在 $JBOSS_HOME/server/default/deploy 目录下; 如果你正在使用的JBoss版本已经有了这个文件,就替换了它。
您可以向这样配置:
@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()); } }
每一个接收到的消息都将导致 onMessage(Message message) 被调用。 大多数Seam的注释将会在MDB内部运行,但你不可以访问持久上下文。
在链接 http://wiki.jboss.org/wiki/Wiki.jsp?page=InboundJavaMail 的 mail-ra.rar 上你可以找到更多的信息。
如果你没有使用JBoss,你依然可以使用 mail-ra.rar,或许你可以在你的程序服务器上找到类似的适配器。
为了在你的应用程序中能够使用电子邮件,要确保 jboss-seam-mail.jar 包含在 WEB-INF/lib 目录中。 如果你在使用JBoss AS,则使用Seam的邮件支持不需要做更多的配置工作了。 否则你可能需要确认你是否有JavaMail的API,一个可供使用的JavaMail API的实现(JBoss AS中使用的API和实现正如作为 lib/mail.jar 跟随Seam发布的包),和一份Java Activation Framework的拷贝(作为 lib/activation.jar 跟随Seam发布)。
Seam的Email模块需要Facelets作为视图技术。将来库的版本可能会添加对JSP的支持。另外,它需要用到seam-ui包。
mailSession 组件使用JavaMail就像与'真实的'SMTP服务器通讯。
如果你在使用JEE环境工作,可以通过JNDI查找可用的JavaMail Session,你也可以使用Seam配置好的Session。
在 Section 28.8, “与邮件相关的组件” 中有关于邮件会话组件属性的详细介绍。
JBossAS deploy/mail-service.xml 配置JavaMail会话捆绑到JNDI。 你需要修改默认的服务配置再应用到你的网络中。这里描述了更加详细的服务 http://wiki.jboss.org/wiki/Wiki.jsp?page=JavaMail
<components xmlns="http://jboss.com/products/seam/components" xmlns:core="http://jboss.com/products/seam/core" xmlns:mail="http://jboss.com/products/seam/mail"> <mail:mail-session session-jndi-name="java:/Mail"/> </components>
这里我们告诉Seam在JNDI中是通过 java:/Mail 来获得邮件Session的。
邮件会话可以通过 components.xml 配置来访问的。 这里我们告诉Seam使用 smtp.example.com 作为SMTP服务器。
<components xmlns="http://jboss.com/products/seam/components" xmlns:core="http://jboss.com/products/seam/core" xmlns:mail="http://jboss.com/products/seam/mail"> <mail:mail-session host="smtp.example.com"/> </components>
Seam的邮件示例采用Meldware(来自 buni.org)作为邮件服务器。 Meldware是提供 SMTP、POP3、IMAP、WebMail、共享日历和图形化的管理工具的于一身的软件; 它是作为一个JEE应用程序编写的,因此可以和你的Seam程序一起部署到JBoss上。
和Seam一起分发的Meldware的版本(在文件夹mail/buni-meldware)为了开发都被特别修改过 - 邮箱、用户和别名(邮件地址)在每次程序部署的时候创建。 如果你希望在产品中不仅仅使用Meldware发送邮件,建议你使用vanilla拷贝。 你也可以使用 meldware 组件来创建邮箱,用户和别名等。
<components xmlns="http://jboss.com/products/seam/components" xmlns:core="http://jboss.com/products/seam/core" xmlns:mail="http://jboss.com/products/seam/mail"> <mail:mail-session host="smtp.example.com"/> <mail:meldware> <mail:users> <value>#{duke}</value> <value>#{root}</value> </mail:users> </mail:meldware> <mail:meldware-user name="duke" username="duke" password="duke"> <mail:aliases> <value>[email protected]</value> <value>[email protected]</value> </mail:aliases> <mail:meldware-user name="root" username="root" password="root" administrator="true" /> </components>
这里我们创建了两个用户,拥有两个邮件地址的 duke 和名为 root 的管理员。
邮件通过使用命名空间 http://jboss.com/products/seam/mail 的标签生成。 文档中在消息的根部通常应该有 message 标签,message标签使Seam准备生成一封邮件。
标准的facelets的模板标签可以如同往常一样地来使用。 你可以在主体内部使用任何JSF标签;如果需要访问外部资源(stylesheets、javascript),那么就要确认是否设置了 urlBase。
邮件消息的根标签
importance — 低、正常或是高。默认是正常,这是设置邮件消息重要程度的标签。
precedence — 设置消息的优先级(例如:突出)
requestReadReceipt —默认是false,如果设置,将会添加阅读回执,阅读回执将会被发给 From: 地址。
urlBase — 如果设置,预设的 requestContextPath 将允许你在邮件中使用形如 <h:graphicImage> 的组件。
设置邮件的发件地址。每封邮件只允许有一个这样的值。
name — 邮件应该来自的名称。
address — 邮件应该来自的地址。
设置回复地址给邮件。每封邮件同样只能有一个这样的值。
address — 邮件来源的地址。
添加一个收件人到邮件。有多个收件人时使用复合的<m:to>标签。 这个标签可以被安全的放置在重复标签<ui:repeat>之类中。
name — 收件人的名字。
address — 收件人的地址。
添加抄送地址到邮件。有多个抄送地址时使用复合的<m:cc>标签。这个标签可以被安全的放置在重复标签<ui:repeat>之类中。
name — 收件人的名字。
address — 收件人的邮件地址。
添加一个秘文抄送人到邮件。有多个秘密抄送地址时使用复合的<m:bcc>标签。 这个标签可以被安全的放置在重复标签<ui:repeat>之类中。
name — 收件人的名字。
address — 收件人的邮件地址。
向邮件添加一个头(例如:X-Sent-From: JBoss Seam)。
name — 要添加的头的名字(例如:X-Sent-From)。
value — 要添加的头的值(例如:JBoss Seam)。
添加一个附件到邮件。
value — 要添加的附件:
String — 在classpath中一个 String 作为到文件的路径被解析。
java.io.File —一个指向 File 对象的EL表达式。
java.net.URL — 一个指向URL对象的EL表达式。
java.io.InputStream — 一个指向 InputStream 类型的EL表达式。 这种情况下,fileName 和 contentType 都必须指定。
byte[] — 一个指向 byte[] 类型的EL表达式。 这种情况下,fileName 和 contentType 都必须指定。
如果值属性被省略:
如果这个标签包含一个 <p:document> 标签,这个被描述的文档将会被生成并且附加到邮件上。 fileName 应该被指定。
如果这个标签包含其它的JSF标签,将会通过它们生成HTML文档并附加到邮件。fileName应该被指定。
fileName — 指定可供使用的已经被附上的文件。
contentType —指定已附上的文件的MIME类型。
设置邮件主题。
设置邮件主体。支持 alternative facet。 比如生成的一个HTML邮件可能包含针对不支持html的阅读器的备选的文本。
type — 如果设为 plain,将会生成一份简单文本邮件,否则将会生成一份HTML邮件。