邮件是Web应用的一个重要部分,常用于邮箱确认、找回密码、发送广告、通知等等。
Java中的JavaMail API不是很易于学习使用,容易编写出冗余易错的代码。Spring 提供了对JavaMail的有效支持,使得发送邮件变得简单愉快。
org.springframework.mail包是Spring Mail支持的顶级包,包下的MailSender,MailMessage两个核心接口和一个SimpleMessageMessage类。
其中MailSender邮件发送器,定义了发送简单邮件的方法,void send(SimpleMailMessage simpleMessage);亦可以发送多个邮件 void send(SimpleMailMessage[] simpleMessages);
MailSender的子接口JavaMailSender及其实现类JavaMailSenderImpl提供的对MIME message的支持,这样我们就可以再邮件中编写Html代码加入图片了。
MailMessage负责邮件本身的信息,包括设置主题,内容,发件人,收件人等方法。
MailMessage有两个实现类,SimpleMailMessage和MimeMailMessage,SimpleMailMessage定义了简单文本邮件,MimeMailMessage则提供了更多丰富的邮件内容支持。
I have trouble in installing PinYin input method, so i have to continue my blog using my poor english... :)And for practice
Talk is cheap, so show the code.
First we need some basic infrastructure, like jdk,maven,and text editor or ide(recommended).
Then we create an maven project from quick-start stereotype and put some dependencies to the pom.xml.
What we need : spring-core,spring-context,spring-context-support, javax.mail and spring-test and some logging artifacts.
Here we begin our project.
create a spring configuration and define some beans to use
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl"> <property name="host" value="${mail.host}"/> <property name="port" value="${mail.port}"/> <property name="username" value="${mail.username}"/> <property name="password" value="${mail.password}"/> <property name="javaMailProperties"> <props> <prop key="mail.smtp.auth">true</prop> </props> </property> </bean> <bean id="simpleMessage" class="org.springframework.mail.SimpleMailMessage"> <property name="from" value="${mail.username}"/> </bean>
Here we create an mailSender instance implemeted by JavaMailSenderImpl and SimpleMailMessage instance.
you could replace the placeholders with your own mail setting.
Then we could use mailSender send simpleMessage for simple text email.
Put the business in a service layer class EmailService, it has a method for sending.
@Service public class EmailService { @Autowired private JavaMailSender javaMailSender; @Autowired private SimpleMailMessage simpleMailMessage; public void sendTo(String to, String subject, String text){ simpleMailMessage.setTo(to); simpleMailMessage.setSubject(subject); simpleMailMessage.setText(text); javaMailSender.send(simpleMailMessage); } }
Then we could test this. Create a test class.
@ContextConfiguration(locations = {"/applicationContext.xml"}) public class EmailServiceTest extends AbstractTestNGSpringContextTests{ @Autowired private EmailService emailService; @Test public void sendSimpleMessageTest(){ String email = "[email protected]"; String subject = "This is send by liuzhengyang for fun"; String text= "This is send by liuzhengyang for fun" + "and i write &!@@@"; emailService.sendTo(email, subject, text); } }
notice your subject and email content should not be Spam like . or this email may be interceptored.Maybe i have to set up my
own mail server to break limitation for sending rate and email content.
Run this test , then i could receive this simple text email.
At production , we need some more complex email then we could use MimeMailMessage.
To use MimeMailMessage we could use MimeMessagePreparator and MimeMessageHelper for simplicity.
public void sendForRegister(final String to, final String subject){ javaMailSender.send(new MimeMessagePreparator() { @Override public void prepare(MimeMessage mimeMessage) throws Exception { MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8"); mimeMessageHelper.setFrom(javaMailSender.getUsername()); mimeMessageHelper.setTo(to); mimeMessageHelper.setSubject(subject); mimeMessageHelper.setText("<html><h1>MimeMailMessage</h1></html>", true); } }); }
For using MimeMessageHelper#setFrom , i change the declaration of JavaMailSender javaMailSender to JavaMailSenderImpl javaMailSender;
Test this , and i receive a h1 email.
And we could add attachments or inline resources to the email.And maybe the setText() in the example above make think of using Servlet to send response,
this is error prone and some hardCoding.For better choice, we could use template like Velocity.
add bean defination for velocity
<bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean"> <property name="velocityProperties"> <value> resource.loader=class class.resource.loader.class=org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader </value> </property> </bean>
We create a velocity template
## for email confirm after registeration <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <style> body{ text-align: center; font-size: large; } #title{ color: #DD3322; } </style> </head> <body> <h3>亲爱的 <span id="title">${username}</span>, 欢迎!!</h3> <div> The life is beautiful and enjoy yourself!<br/> </div> <div> 请点击一下链接完成确认:<br/> <a href="${url}">${url}</a><br/> (如果链接不能点击,请复制并粘贴到浏览器的地址栏,然后按回车键,该链接48小时内有效。)<br/> </div> <div> <img src="cid:img0"/> </div> </body> </html>
And then use it for mailing.
public void sendForRegister(final String to, final String subject){ javaMailSender.send(new MimeMessagePreparator() { @Override public void prepare(MimeMessage mimeMessage) throws Exception { MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8"); mimeMessageHelper.setFrom(javaMailSender.getUsername()); mimeMessageHelper.setTo(to); mimeMessageHelper.setSubject(subject); Map<String, Object> model = new HashMap<String, Object>(); model.put("username","somenewuserfromuserobject"); model.put("url","urlfromuserobject"); mimeMessageHelper.setText(VelocityEngineUtils.mergeTemplateIntoString(velocityEngine,"/template/mail/registeration-confirmation.vm","UTF-8",model), true); ClassPathResource resource = new ClassPathResource("/image/mail/img1.png"); System.out.println(resource.contentLength()); mimeMessageHelper.addInline("img0", resource); } }); }
This is the basic using of Spring Mail Support that i conclued.
There are several things to improve ,such as adding aop to email business , making this as as asynchronous task.