我們系統存在大量發送郵件的需求,項目使用的是Spring框架而JavaMail也能很好的跟Spring進行集成,由於發送郵件最好還是使用異步進行發送,所以這里就采用線程池+JavaMail進行郵件發送,下面看具體代碼實現:
Step1、引入JavaMail
<mail.version>1.4.7</mail.version> <dependency> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> <version>${mail.version}</version> </dependency>
Step2、Spring配置文件中配置MailSender和線程池
<!--MailSender--> <bean id="javaMailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl"> <property name="host" value="${email.host}"/> <property name="username" value="${email.username}"/> <property name="password" value="${email.password}"/> <property name="javaMailProperties"> <props> <prop key="mail.smtp.auth">true</prop> <prop key="mail.smtp.timeout">25000</prop> <!-- <prop key="mail.smtp.starttls.enable">true</prop> <prop key="mail.smtp.socketFactory.class">javax.net.ssl.SSLSocketFactory</prop> --> </props> </property> </bean> <!--配置線程池--> <bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> <!-- 核心線程數 --> <property name="corePoolSize" value="${executor.corePoolSize}" /> <!-- 最大線程數 --> <property name="maxPoolSize" value="${executor.maxPoolSize}" /> <!-- 最大隊列數 --> <property name="queueCapacity" value="${executor.queueCapacity}" /> <!-- 線程池維護線程所允許的空閑時間 --> <property name="keepAliveSeconds" value="${executor.keepAliveSeconds}" /> </bean>
Step3、新建郵件實體類,方便業務處理
import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.util.Assert; import javax.mail.internet.AddressException; import java.util.Arrays; /** * <p> * <code>MailEntry</code> * </p> * Description: * 郵件實體類 * @author jianzh5 * @version 2017/3/31 17:00 * @since 1.0 */ public class MailEntry { /** * 收件人 */ private String[] recipients; /** * 抄送人 */ private String[] carbonCopy; /** * 主題 */ private String subject; /** * 內容 */ private String text; public String getSubject() { return subject; } public void setSubject(String subject) { this.subject = subject; } public String getText() { return text; } public void setText(String text) { this.text = text; } public String[] getRecipients() { return recipients.clone(); } public void setRecipients(String[] recipients) throws AddressException { Assert.isTrue(ArrayUtils.isNotEmpty(recipients),"收件人不能為空"); String[] addresses = new String[recipients.length]; for (int i = 0; i < addresses.length; i++) { addresses[i] = parseAddress(recipients[i]); } this.recipients = addresses; } public String[] getCarbonCopy() { if(ArrayUtils.isNotEmpty(carbonCopy)){ return carbonCopy.clone(); } return ArrayUtils.EMPTY_STRING_ARRAY; } public void setCarbonCopy(String[] carbonCopy) throws AddressException { String[] addresses = new String[carbonCopy.length]; for (int i = 0; i < addresses.length; i++) { addresses[i] = parseAddress(carbonCopy[i]); } this.carbonCopy = addresses; } /** * @desc 只要設定郵件接受人的域賬號即可自動增加企業后綴 * @author jianzh5 * @date 2017/4/1 13:43 * @param recipient 收件人域賬號 * @return 帶企業后綴的郵箱地址 * @throws AddressException */ private String parseAddress(String recipient) throws AddressException { if(StringUtils.isEmpty(recipient)){ throw new AddressException("郵箱賬號不能為空",recipient); } return recipient + "@company.com"; } @Override public String toString() { return "MailEntry{" + "recipients=" + Arrays.toString(recipients) + ", carbonCopy=" + Arrays.toString(carbonCopy) + ", subject='" + subject + '\'' + ", text='" + text + '\'' + '}'; } }
說明:由於我們是使用企業郵箱發送郵件,而一般業務都只能取到公司用戶名而非真正的郵箱地址,所以在上面實體類里進行了一次轉換,如果能直接拿到郵箱地址的話上面的轉換是不需要的。收件人和抄送人都是支持數組形式的參數,所以在這里直接使用數組作為收件人、抄送人屬性,發送郵件的時候只要直接設置成數組參數即可。
Step4、發送郵件業務層實現
import org.apache.commons.lang3.ArrayUtils; import org.springframework.core.task.TaskExecutor; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.stereotype.Service; import javax.annotation.Resource; import javax.mail.MessagingException; import javax.mail.internet.MimeMessage; /** * <p> * <code>MailServiceImpl</code> * </p> * Description: * 郵件系統實現類 * @author jianzh5 * @version 2017/3/31 17:10 * @since 1.0 */ @Service public class MailServiceImpl implements IMailService{ private LoggerUtil logger = LoggerUtil.getLogger(this.getClass()); @Resource private TaskExecutor taskExecutor; @Resource private JavaMailSender javaMailSender; @Override public void sendMail(MailEntry mailEntry) { MimeMessage message = javaMailSender.createMimeMessage(); try { MimeMessageHelper helper = new MimeMessageHelper(message, true, "utf-8"); helper.setFrom("xxx@company.com"); helper.setTo(mailEntry.getRecipients()); //收件人 if(ArrayUtils.isNotEmpty(mailEntry.getCarbonCopy())){ helper.setCc(mailEntry.getCarbonCopy()); //抄送人 } helper.setSubject(mailEntry.getSubject()); helper.setText(mailEntry.getText(),true);//設置為TRUE則可以使用Html標記 addSendMailTask(message); } catch (MessagingException e) { // e.printStackTrace(); logger.error("郵件轉換異常,郵件詳細信息為{}",e.getMessage()); } } /** * @desc 使用多線程發送郵件 * @author jianzh5 * @date 2017/4/1 11:41 * @param message MimeMessage郵件封裝類 */ private void addSendMailTask(final MimeMessage message){ try{ taskExecutor.execute(new Runnable() { @Override public void run() { javaMailSender.send(message); } }); }catch (Exception e){ logger.error("郵件發送異常,郵件詳細信息為{}",e.getMessage()); } } }