Spring v3.0.2 Learning Note 14 - Send Email with Spring
2010-10-25 11:16
579 查看
Reference Library
%SPRING%/dist/org.springframework.core-3.0.2.RELEASE.jar
%SPRING%/dist/org.springframework.asm-3.0.2.RELEASE.jar
%SPRING%/dist/org.springframework.beans-3.0.2.RELEASE.jar
%SPRING%/dist/org.springframework.context-3.0.2.RELEASE.jar
%SPRING%/dist/org.springframework.context.support-3.0.2.RELEASE.jar
%SPRING%/dist/org.springframework.expression-3.0.2.RELEASE.jar
%SPRING%/dist/org.springframework.aspects-3.0.2.RELEASE.jar
%SPRING%/dist/org.springframework.aop-3.0.2.RELEASE.jar
%SPRING_DEP%/org.apache.commons/org.apache.common/com.springsource.org.apache.commons.logging/1.1.1/com.springsource.org.apache.commons.logging-1.1.1.jar
%SPRING_DEP%/javax.mail/com.springsource.javax.mail/1.4.0/com.springsource.javax.mail-1.4.0.jar
%SPRING_DEP%/org.aopalliance/com.springsource.org.aopalliance/1.0.0/com.springsource.org.aopalliance-1.0.0.jar
create a java project and add above library files to project classpath.
This is the interface class:
// interface class
package test.spring.email;
public interface AccountNotifier {
public void notifyAccount(String accountId, String password);
}
Send Email Using JavaMail API
package test.spring.email;
import java.util.Properties;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import org.springframework.stereotype.Component;
@Component
public class AccountNotifierImpl implements AccountNotifier {
@Override
public void notifyAccount(String accountId, String password) {
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.port", "587");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
Session session = Session.getDefaultInstance(props,
new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("<gmail account>", "<gmail password>");
}
});
session.setDebug(true);
try {
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress("ABC@gmail.com"));
message.setRecipients(Message.RecipientType.TO, InternetAddress
.parse("DEF@yahoo.com"));
message.setSubject("Account Notification Test");
message.setText("Dear Customer,/n/n" + "Account No. : " + accountId
+ "/n" + "Password : " + password);
Transport.send(message);
System.out.println("success!");
} catch (MessagingException e) {
throw new RuntimeException(e);
}
}
}
Firstly, open a mail session connecting to an SMTP server by defining the properties. Then create a message from this session for constructing your e-mail. After that, send the e-mail by making a call to Transport.send().
This is the spring configuration file.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <context:component-scan base-package="test.spring.email" />
</beans>
Run this junit test, you can see the email has been sent out.
// junit test
package test.spring.email;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class EmailTester {
@BeforeClass
public static void setUpBeforeClass() throws Exception {
}
@AfterClass
public static void tearDownAfterClass() throws Exception {
}
@Test
public void testEmailSender() {
ApplicationContext context = new ClassPathXmlApplicationContext(
"spring.xml");
AccountNotifier accountNotifier = (AccountNotifier) context
.getBean("accountNotifierImpl");
accountNotifier.notifyAccount("Account12", "pwd123");
}
}
Send Email with Spring's MailSender
The core interface of Spring’s e-mail support is MailSender. If only sending plain text in the email, use this interface.
// implement class
package test.spring.email;
import javax.annotation.Resource;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.stereotype.Component;
@Component
public class AccountNotifierMailSenderImpl implements AccountNotifier {
@Resource
private MailSender mailSender;
public void setMailSender(MailSender mailSender) {
this.mailSender = mailSender;
}
@Override
public void notifyAccount(String accountId, String password) {
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom("ABC@yahoo.com");
message.setTo("DEF@yahoo.com");
message.setSubject("Account Notifier with Spring Mail Sender");
message.setText("Dear Customer,/n/n" + "Account No. : " + accountId
+ "/n" + "Password : " + password);
mailSender.send(message);
}
}
then, configure mailSender in spring as follows.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <context:component-scan base-package="test.spring.email" />
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="smtp.gmail.com" />
<property name="port" value="587" />
<property name="username" value="<your account>" />
<property name="password" value="<your password>" />
<property name="javaMailProperties">
<props>
<!-- Use SMTP-AUTH to authenticate to SMTP server -->
<prop key="mail.smtp.auth">true</prop>
<!-- Use TLS to encrypt communication with SMTP server -->
<prop key="mail.smtp.starttls.enable">true</prop>
<!-- print session debug info -->
<prop key="mail.debug">true</prop>
</props>
</property>
</bean>
</beans>
If you have a JavaMail session configured in your application server, you can first look it up with the help of JndiObjectFactoryBean.
<bean id="mailSession" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="mail/Session" />
</bean>
Or you can look up a JavaMail session through the <jee:jndi-lookup> element if you are using Spring 2.0 or later.
<jee:jndi-lookup id="mailSession" jndi-name="mail/Session" />
You can inject the JavaMail session into JavaMailSenderImpl for its use. In this case, you no longer need to set the host, port, username, or password.
<bean id="mailSender"
class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="session" ref="mailSession" />
</bean>
If you are using tomcat 6.x, you can define JavaMail session as follows.
Email Template
Sending MIME Message
// change bean definition
<bean id="mailMessage" class="org.springframework.mail.SimpleMailMessage">
<!-- <property name="from" value="ABC@gmail.com" /> -->
<property name="from">
<value><![CDATA[Application Notifier <noreply@gmail.com>]]></value>
</property>
<!-- <property name="to" value="DEF@yahoo.com" /> -->
<property name="to">
<value><![CDATA[System Customer <xiang.wang@ufinity.com>]]></value>
</property>
<property name="subject"
value="Account Notification Test with Email Template" />
<property name="text">
<value>
<![CDATA[ //---<<<<< include HTML tag within email content
<html><body>
Dear Customer,<p/>
Account No. :<b><style color="red"> %s</style></b><br/>
Password : %s<br/>
<br/>
Now you are allowed to access:<br/>
<ul>
<li><a href="www.yahoo.com">yahoo</a></li>
<li><a href="www.google.com">google</a></li>
</ul>
<br/>
XXX Administrator
</body></html>
]]>
</value>
</property>
</bean>
// implement class
package test.spring.email;
import java.io.File;
import javax.annotation.Resource;
import javax.mail.internet.MimeMessage;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.mail.javamail.MimeMessagePreparator;
import org.springframework.stereotype.Component;
@Component
public class AccountNotifierMailSenderImpl implements AccountNotifier {
@Resource
private JavaMailSender mailSender;
@Resource
private SimpleMailMessage mailMessage;
// should be JavaMailSende, not MailSender instead
public void setMailSender(JavaMailSender mailSender) {
this.mailSender = mailSender;
}
public void setMailMessage(SimpleMailMessage mailMessage) {
this.mailMessage = mailMessage;
}
@Override
public void notifyAccount(final String accountId, final String password) {
MimeMessagePreparator preparator = new MimeMessagePreparator() {
public void prepare(MimeMessage mimeMessage) throws Exception {
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,
true);
helper.setFrom(mailMessage.getFrom());
helper.setTo(mailMessage.getTo());
helper.setSubject(mailMessage.getSubject());
helper.setText(String.format(mailMessage.getText(), accountId,
password), true); // must set true,otherwise, will show plain text in email
// add attachment
FileSystemResource file = new FileSystemResource(new File(
"d:/logo.jpg"));
helper.addAttachment("mylog.jpg", file);
}
};
mailSender.send(preparator);
}
}
In the prepare() method, you can prepare the MimeMessage object, which is precreated for JavaMailSender. If there’s any exception thrown, it will be converted into Spring’s mail runtime exception automatically.
%SPRING%/dist/org.springframework.core-3.0.2.RELEASE.jar
%SPRING%/dist/org.springframework.asm-3.0.2.RELEASE.jar
%SPRING%/dist/org.springframework.beans-3.0.2.RELEASE.jar
%SPRING%/dist/org.springframework.context-3.0.2.RELEASE.jar
%SPRING%/dist/org.springframework.context.support-3.0.2.RELEASE.jar
%SPRING%/dist/org.springframework.expression-3.0.2.RELEASE.jar
%SPRING%/dist/org.springframework.aspects-3.0.2.RELEASE.jar
%SPRING%/dist/org.springframework.aop-3.0.2.RELEASE.jar
%SPRING_DEP%/org.apache.commons/org.apache.common/com.springsource.org.apache.commons.logging/1.1.1/com.springsource.org.apache.commons.logging-1.1.1.jar
%SPRING_DEP%/javax.mail/com.springsource.javax.mail/1.4.0/com.springsource.javax.mail-1.4.0.jar
%SPRING_DEP%/org.aopalliance/com.springsource.org.aopalliance/1.0.0/com.springsource.org.aopalliance-1.0.0.jar
create a java project and add above library files to project classpath.
This is the interface class:
// interface class
package test.spring.email;
public interface AccountNotifier {
public void notifyAccount(String accountId, String password);
}
Send Email Using JavaMail API
package test.spring.email;
import java.util.Properties;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import org.springframework.stereotype.Component;
@Component
public class AccountNotifierImpl implements AccountNotifier {
@Override
public void notifyAccount(String accountId, String password) {
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.port", "587");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
Session session = Session.getDefaultInstance(props,
new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("<gmail account>", "<gmail password>");
}
});
session.setDebug(true);
try {
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress("ABC@gmail.com"));
message.setRecipients(Message.RecipientType.TO, InternetAddress
.parse("DEF@yahoo.com"));
message.setSubject("Account Notification Test");
message.setText("Dear Customer,/n/n" + "Account No. : " + accountId
+ "/n" + "Password : " + password);
Transport.send(message);
System.out.println("success!");
} catch (MessagingException e) {
throw new RuntimeException(e);
}
}
}
Firstly, open a mail session connecting to an SMTP server by defining the properties. Then create a message from this session for constructing your e-mail. After that, send the e-mail by making a call to Transport.send().
This is the spring configuration file.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <context:component-scan base-package="test.spring.email" />
</beans>
Run this junit test, you can see the email has been sent out.
// junit test
package test.spring.email;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class EmailTester {
@BeforeClass
public static void setUpBeforeClass() throws Exception {
}
@AfterClass
public static void tearDownAfterClass() throws Exception {
}
@Test
public void testEmailSender() {
ApplicationContext context = new ClassPathXmlApplicationContext(
"spring.xml");
AccountNotifier accountNotifier = (AccountNotifier) context
.getBean("accountNotifierImpl");
accountNotifier.notifyAccount("Account12", "pwd123");
}
}
Send Email with Spring's MailSender
The core interface of Spring’s e-mail support is MailSender. If only sending plain text in the email, use this interface.
// implement class
package test.spring.email;
import javax.annotation.Resource;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.stereotype.Component;
@Component
public class AccountNotifierMailSenderImpl implements AccountNotifier {
@Resource
private MailSender mailSender;
public void setMailSender(MailSender mailSender) {
this.mailSender = mailSender;
}
@Override
public void notifyAccount(String accountId, String password) {
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom("ABC@yahoo.com");
message.setTo("DEF@yahoo.com");
message.setSubject("Account Notifier with Spring Mail Sender");
message.setText("Dear Customer,/n/n" + "Account No. : " + accountId
+ "/n" + "Password : " + password);
mailSender.send(message);
}
}
then, configure mailSender in spring as follows.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <context:component-scan base-package="test.spring.email" />
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="smtp.gmail.com" />
<property name="port" value="587" />
<property name="username" value="<your account>" />
<property name="password" value="<your password>" />
<property name="javaMailProperties">
<props>
<!-- Use SMTP-AUTH to authenticate to SMTP server -->
<prop key="mail.smtp.auth">true</prop>
<!-- Use TLS to encrypt communication with SMTP server -->
<prop key="mail.smtp.starttls.enable">true</prop>
<!-- print session debug info -->
<prop key="mail.debug">true</prop>
</props>
</property>
</bean>
</beans>
If you have a JavaMail session configured in your application server, you can first look it up with the help of JndiObjectFactoryBean.
<bean id="mailSession" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="mail/Session" />
</bean>
Or you can look up a JavaMail session through the <jee:jndi-lookup> element if you are using Spring 2.0 or later.
<jee:jndi-lookup id="mailSession" jndi-name="mail/Session" />
You can inject the JavaMail session into JavaMailSenderImpl for its use. In this case, you no longer need to set the host, port, username, or password.
<bean id="mailSender"
class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="session" ref="mailSession" />
</bean>
If you are using tomcat 6.x, you can define JavaMail session as follows.
<Context path="/myapp" docBase="myapp">
<!-- JavaMail session factory --> <Resource name="mail/Session" auth="Container" type="javax.mail.Session" username="yourusername" password="yourpassword" mail.debug="true" mail.user="yourusername" mail.password="yourpassword" mail.transport.protocol="smtp" mail.smtp.host="your.smtphost.com" mail.smtp.auth="true" mail.smtp.port="25" mail.smtp.starttls.enable="true"/> </Context>
Email Template
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<context:component-scan base-package="test.spring.email" /> <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl"> <property name="host" value="smtp.gmail.com" /> <property name="port" value="587" /> <property name="username" value="<yourname>" /> <property name="password" value="<password>" /> <property name="javaMailProperties"> <props> <!-- Use SMTP-AUTH to authenticate to SMTP server --> <prop key="mail.smtp.auth">true</prop> <!-- Use TLS to encrypt communication with SMTP server --> <prop key="mail.smtp.starttls.enable">true</prop> <prop key="mail.debug">true</prop> </props> </property> </bean> <bean id="mailMessage " class="org.springframework.mail.SimpleMailMessage"> <!-- <property name="from" value="ABC@gmail.com" /> --> <property name="from"> <value><![CDATA[Application Notifier <noreply@gmail.com>]]></value> </property> <!-- <property name="to" value="DEF@yahoo.com" /> --> <property name="to"> <value><![CDATA[System Customer <DEF@yahoo.com>]]></value> </property> <property name="subject" value="Account Notification Test with Email Template" /> <property name="text"> <value> <![CDATA[ Dear Customer, Account No. : %s Password : %s XXX Administrator ]]> </value> </property> </bean> </beans>
package test.spring.email; import javax.annotation.Resource; import org.springframework.mail.MailSender; import org.springframework.mail.SimpleMailMessage; import org.springframework.stereotype.Component; @Component public class AccountNotifierMailSenderImpl implements AccountNotifier { @Resource private MailSender mailSender; @Resource private SimpleMailMessage mailMessage; public void setMailSender(MailSender mailSender) { this.mailSender = mailSender; } public void setMailMessage(SimpleMailMessage mailMessage) { this.mailMessage = mailMessage; } @Override public void notifyAccount(String accountId, String password) { SimpleMailMessage message = new SimpleMailMessage(mailMessage); message.setText(String.format(mailMessage.getText(), accountId, password)); mailSender.send(message); } }Note the placeholders %s, which will be replaced by message parameters through String.format().Of course, you can also use a powerful templating language such as Velocity or FreeMarker to generate the message text according to a template. It’s also a good practice to separate mail message templates from bean configuration files.Each time you send e-mail, you can construct a new SimpleMailMessage instance from this injected template. Then you can generate the message text using String.format() to replace the %s placeholders with your message parameters.
Sending MIME Message
// change bean definition
<bean id="mailMessage" class="org.springframework.mail.SimpleMailMessage">
<!-- <property name="from" value="ABC@gmail.com" /> -->
<property name="from">
<value><![CDATA[Application Notifier <noreply@gmail.com>]]></value>
</property>
<!-- <property name="to" value="DEF@yahoo.com" /> -->
<property name="to">
<value><![CDATA[System Customer <xiang.wang@ufinity.com>]]></value>
</property>
<property name="subject"
value="Account Notification Test with Email Template" />
<property name="text">
<value>
<![CDATA[ //---<<<<< include HTML tag within email content
<html><body>
Dear Customer,<p/>
Account No. :<b><style color="red"> %s</style></b><br/>
Password : %s<br/>
<br/>
Now you are allowed to access:<br/>
<ul>
<li><a href="www.yahoo.com">yahoo</a></li>
<li><a href="www.google.com">google</a></li>
</ul>
<br/>
XXX Administrator
</body></html>
]]>
</value>
</property>
</bean>
// implement class
package test.spring.email;
import java.io.File;
import javax.annotation.Resource;
import javax.mail.internet.MimeMessage;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.mail.javamail.MimeMessagePreparator;
import org.springframework.stereotype.Component;
@Component
public class AccountNotifierMailSenderImpl implements AccountNotifier {
@Resource
private JavaMailSender mailSender;
@Resource
private SimpleMailMessage mailMessage;
// should be JavaMailSende, not MailSender instead
public void setMailSender(JavaMailSender mailSender) {
this.mailSender = mailSender;
}
public void setMailMessage(SimpleMailMessage mailMessage) {
this.mailMessage = mailMessage;
}
@Override
public void notifyAccount(final String accountId, final String password) {
MimeMessagePreparator preparator = new MimeMessagePreparator() {
public void prepare(MimeMessage mimeMessage) throws Exception {
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,
true);
helper.setFrom(mailMessage.getFrom());
helper.setTo(mailMessage.getTo());
helper.setSubject(mailMessage.getSubject());
helper.setText(String.format(mailMessage.getText(), accountId,
password), true); // must set true,otherwise, will show plain text in email
// add attachment
FileSystemResource file = new FileSystemResource(new File(
"d:/logo.jpg"));
helper.addAttachment("mylog.jpg", file);
}
};
mailSender.send(preparator);
}
}
In the prepare() method, you can prepare the MimeMessage object, which is precreated for JavaMailSender. If there’s any exception thrown, it will be converted into Spring’s mail runtime exception automatically.
相关文章推荐
- Spring v3.0.2 Learning Note 15 - Use Velocity Email Template with Spring
- Spring v3.0.2 Learning Note 1 - Introduction to Spring Framework
- Spring v3.0.2 Learning Note 16 - Integrate With Hessian
- send Email with asp.net
- ISSCC 2017论文导读 Session 14:A 288μW Programmable Deep-Learning Processor with 270KB On-Chip Weight
- Spring v3.0.2 Learning Note 9 - Classpath Scanning
- How to Send an Email Using UTL_SMTP with Authenticated Mail Server
- [zz]Send email with attachment(s) in Python
- How to Send an HTTP Header With Every Request With Spring RestTemplate
- How to Send an Email Using UTL_SMTP with Authenticated Mail Server
- Send Email and Attachments with ASP.Net...
- Paper Note - Learning to Hash with Binary Deep Neural Network
- SpringEmail with Velocity template date and number formatting
- [Paper note] FlowNet: Learning Optical Flow with Convolutional Networks
- READING NOTE: Learning Spatial Regularization with Image-level Supervisions for Multi-label ...
- Send email with zip attachment
- Send email to multiple users with sharepoint workflow
- Send email with attachment
- send email with formatted table
- How to Send an Email Using UTL_SMTP with Authenticated Mail Server