java消息高效发送,Java Mail + 消息队列 高效率发送邮件

本文主要是讲述JavaMail 和 消息队列的一些简单应用,这是第一次写博客,有很多不足的地方希望各位看客给出宝贵建议,另外本文写的不对的地方,请各位大神勿喷!!!

很多人都会在各个系统里面遇到发送邮件的功能,这次开博写文章也是在整理过程中发现,团队中有个新来的小童鞋对发送邮件这块不是很熟,所以自己准备写一个简单的样例。

这里加了一个消息队列主要是用于高并发的情况下,对邮件发送的控制,并可以对消息进行缓存,防止消息丢失。

话不多说直接上代码:

用maven对项目进行的管理,pom.xml

javax.mail

mail

1.4.7

邮件实体:

packagecom.test.utils.mail;importjava.io.Serializable;/***

*@author**/

public classMailVo {/*** 注释内容*/

private static final long serialVersionUID = 1L;privateString receiver;privateString subject;privateString content;publicString getReceiver() {returnreceiver;

}public voidsetReceiver(String receiver) {this.receiver =receiver;

}publicString getSubject() {returnsubject;

}public voidsetSubject(String subject) {this.subject =subject;

}publicString getContent() {returncontent;

}public voidsetContent(String content) {this.content =content;

}public static longgetSerialversionuid() {returnserialVersionUID;

}

}

邮件基本配置config.properties

#mail smtp host

mail.smtp.host=smtp.exmail.qq.com

mail.smtp.port= 465mail.smtp.username=test

mail.sender=[email protected]

mail.smtp.password= test

很多人用的是多线程来做的这个地方,我考虑了下,我觉得用队列比较合适,因为如果有大量需要发送邮件的时候,新建太多的线程会对系统产生不必要的开销,虽然可以集合线程池的方式来做,当然如果是邮件业务比较多,多线程的并发会好点。

我考虑了下,有时候邮件业务不是很多,所以,我给单线程加了个状态维护,在3分钟内没有任务,则销毁该线程,等待新的任务再重新创建新的线程。

packagecom.test.utils.mail;importjava.util.concurrent.ArrayBlockingQueue;importjava.util.concurrent.BlockingQueue;importjava.util.concurrent.TimeUnit;importorg.apache.log4j.Logger;/*** 邮件发送管理插件

* 主要用于管理邮件队列和发送邮件

*@author**/

public classSendMailManager{private static Logger logger = Logger.getLogger(SendMailManager.class);//缓存发送邮件的队列

public static BlockingQueue queue = new ArrayBlockingQueue(2000);//发送邮件线程状态

private static boolean isRunning = false;//超时时间间隔

public static long TIMEOUT_INTERVAL = 3*60*1000;public static booleansendMail(MailVo mail){boolean rsp = false;try{//阻塞3秒

rsp = queue.offer(mail, 3, TimeUnit.SECONDS);if(!rsp){throw new Exception("服务器发送邮件繁忙,请稍后再发");

}if(!isRunning){

startup();

isRunning= true;

}

}catch(Exception e) {

logger.error("添加发送邮件队列出错", e);

}returnrsp;

}public static voidstartup(){if(isRunning){return;

}

Thread th= newThread(){

@Overridepublic voidrun(){

logger.debug("邮件发送消息线程启动");long timestamp =System.currentTimeMillis();while(isRunning)

{long timeout = timestamp +TIMEOUT_INTERVAL;if(System.currentTimeMillis()>timeout)

{//空跑一段时间(3分钟)后线程退出

break;

}try{if(queue.size()==0)

{

Thread.sleep(1000);continue;

}

timestamp=System.currentTimeMillis();

MailVo mail=queue.poll();

MailUtil.sendMail(mail);//发送一个邮件休息2秒,防止发送过快,导致主油箱被锁定

Thread.sleep(2000);

}catch(Exception e)

{

logger.error("邮件推送线程出错",e);

}

}

isRunning= false;

logger.debug("邮件发送线程停止。");

}

};

th.start();

}

}

邮件发送工具:

packagecom.test.utils.mail;importjava.io.UnsupportedEncodingException;importjava.security.GeneralSecurityException;importjava.util.ArrayList;importjava.util.List;importjavax.mail.MessagingException;importjavax.mail.Session;importjavax.mail.Transport;importjavax.mail.internet.InternetAddress;importjavax.mail.internet.MimeMessage;importjavax.mail.internet.MimeUtility;importorg.apache.log4j.Logger;importorg.springframework.util.StringUtils;importcom.sun.mail.smtp.SMTPSendFailedException;importcom.sun.mail.util.MailSSLSocketFactory;importcom.test.constant.Config;importcom.test.utils.PropUtil;/*** @描述:

*

*@author作者 :**/

public classMailUtil {private static Logger logger = Logger.getLogger(MailUtil.class);public static booleansendMail(MailVo mailVo){boolean flag = false;

PropUtil pro= newPropUtil(Config.CONFIG_PATH);

String smtpHost= "";

String smtpport= "";

String from= "";

String password= "";

String to= "";

String subject= "";

String messageText= "";try{

smtpHost=pro.getValue(Config.MAIL_SMTP_HOST);

smtpport=pro.getValue(Config.MAIL_SMTP_PORT);

from=pro.getValue(Config.MAIL_SENDER);

password=pro.getValue(Config.MAIL_SMTP_PASSWORD);

to=mailVo.getReceiver();

subject=mailVo.getSubject();

messageText=mailVo.getContent();int sendFlag =sendMessage(smtpHost, smtpport, from, password, to, subject, messageText);

flag= true;if(sendFlag == 200){

logger.debug("邮件发送成功:发件人 = " + from + "; 收件人 = " + to + "; 主题 = " + subject + "; 内容 = " +messageText);

}else{

logger.debug("邮件发送失败:发件人 = " + from + "; 收件人 = " + to + "; 主题 = " + subject + "; 内容 = " +messageText);

}

}catch(Exception e) {

logger.debug("发送邮件失败,失败内容:smtpHost = " +smtpHost);

logger.debug("发送邮件失败,失败内容:smtpport = " +smtpport);

logger.debug("发送邮件失败,失败内容:from = " +from);

logger.debug("发送邮件失败,失败内容:password = " +password);

logger.debug("发送邮件失败,失败内容:to = " +to);

logger.debug("发送邮件失败,失败内容:smtpHost = " +smtpHost);

logger.debug("发送邮件失败,失败内容:subject = " +subject);

logger.debug("发送邮件失败,失败内容:messageText = " +messageText);

logger.error("发送邮件失败", e);

}returnflag;

}public static intsendMessage(String smtpHost,String smtpport,

String from, String password, String to,

String subject, String messageText){try{//1、配置邮件基本属性

java.util.Properties props = newjava.util.Properties();//2、判断是否需要开启SSL

if(!StringUtils.isEmpty(smtpport) && smtpport.equals("465")){

MailSSLSocketFactory sf;try{

sf= newMailSSLSocketFactory();

sf.setTrustAllHosts(true);

props.put("mail.smtp.ssl.enable", "true");//props.put("mail.smtp.ssl.checkserveridentity", "true");

props.put("mail.smtp.ssl.socketFactory", sf);

}catch(GeneralSecurityException e1) {

logger.error("开始SSL设置出错", e1);

}

}

props.setProperty("mail.smtp.auth", "true");//指定是否需要SMTP验证

props.setProperty("mail.smtp.host", smtpHost);//指定SMTP服务器

props.setProperty("mail.smtp.port", smtpport);//指定SMTP服务器端口

props.put("mail.transport.protocol", "smtp");

Session mailSession=Session.getInstance(props);

mailSession.setDebug(true);//是否在控制台显示debug信息//3、构建发送邮件的具体消息体

logger.debug("Constructing message - from=" + from + " to=" +to);

String nick= javax.mail.internet.MimeUtility.encodeText("邮件用户昵称,根据自己实际定义");//设置发送人

InternetAddress fromAddress = new InternetAddress(nick+" ");//设置接收人

InternetAddress toAddress;

toAddress= newInternetAddress(to);

MimeMessage testMessage= newMimeMessage(mailSession);try{

testMessage.setFrom(fromAddress);

}catch(MessagingException e) {

logger.error(e);return 535;

}try{

testMessage.addRecipient(javax.mail.Message.RecipientType.TO, toAddress);

}catch(MessagingException e) {

logger.error(e);return 534;

}

testMessage.setSentDate(newjava.util.Date());

testMessage.setSubject(MimeUtility.encodeText(subject,"gb2312","B"));//设置消息文本

testMessage.setContent(messageText, "text/html;charset=gb2312");

System.out.println("Message constructed");

Transport transport;

transport= mailSession.getTransport("smtp");//设置邮箱服务器 用户名 密码

transport.connect(smtpHost, from, password);

transport.sendMessage(testMessage, testMessage.getAllRecipients());

transport.close();return 200;

}catch(SMTPSendFailedException e){

logger.error(e);return 550;

}catch(MessagingException e) {

logger.error(e);return 500;

} catch(UnsupportedEncodingException e) {

logger.error(e);return 501;//文本消息有错

}

}

}

本文是用的腾讯企业邮箱作为测试的,但是发现在测试过程中,很容易造成:

javax.mail.AuthenticationFailedException: 535 Error: authentication failed, system busy

用于登录失败,所以整理了下具体原因:

1:邮箱有独立密码,非邮箱登录密码

2:邮箱设置的客户端单独授权码

进入邮箱,点击设置:

ef270e5ab843a6f9f839fac258fdeeae.png

867aac5f32d0c58289dfa002ae9d2145.png

额,第一次写文,话不多说,直接都是给的精华,希望初学者能理解到。

另外代码封装不是很好,主要是为了测试,请在自己项目中重新封装下,以便于程序的扩展。

原文:http://www.cnblogs.com/h-kj/p/7780748.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值