`
lee1177
  • 浏览: 117771 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

一个简单的异步队列邮件发送实现

阅读更多

企业项目中经常使用到邮件发送,尤其在流程审批伴随大量的触发邮件,为提供效率邮件自然设置为异步发送,但单纯多线程异步又造成了先后混乱的现象。所以做了个简单的单线程异步发送队列来处理。

1、把原有的邮件发送服务类做了个修改

ublic class MailSendService {
	private @Value("${system.sendmail.from}") String mailForm;  
	@Autowired
	private JavaMailSender javaMailSender; // 邮件发送对象,采用的是spring中的实现类org.springframework.mail.javamail.JavaMailSenderImpl
	@Autowired
	private MailBoxDao mailBoxDao;  //邮件信息记录处理DAO
	@Autowired
	private MailTemplateDao mailTemplateDao;  //邮件模板处理DAO
	
	/**
	 * 一个默认的邮件发送线程对象
	 */
	private static MailSendTask mailSendTask;

	/**
	 * 发送简单邮件
	 * @Methods Name sendByTempate
	 * @Create In 2014年11月11日 By lee
	 * @param templateCode
	 * @param to
	 * @param titleParam
	 * @param contextParam
	 */
	public void sendByTempate(String templateCode, String to, 
			Map<String,String> titleParam, Map<String,String> contentParam){
		sendByTempate(templateCode, to, null, null, titleParam, contentParam, null);
	}
	
	/**
	 * 发送邮件
	 * @Methods Name sendByTempate
	 * @Create In 2014年11月11日 By lee
	 * @param templateCode
	 * @param to
	 * @param cc
	 * @param bcc
	 * @param titleParam
	 * @param contextParam
	 * @param fileParam
	 */
	public void sendByTempate(String templateCode, String to, String cc, String bcc,
			Map<String,String> titleParam, Map<String,String> contentParam, List<String> fileParam){
		MailTemplate template = mailTemplateDao.findByCode(templateCode);
		MailBox mailBox = new MailBox();
		mailBox.setTouser(to);
		mailBox.setCc(bcc);
		mailBox.setBcc(bcc);
		mailBox.setTitle(emailParam(template.getTitle(),titleParam));
		mailBox.setContent(emailParam(template.getContent(),contentParam));
		mailBox.setFilePath(StrUtils.join(fileParam, ";"));
		mailBox.setSendState(MailBox.STATE_READY);
		mailBox = mailBoxDao.save(mailBox);
		readSend(mailBox);
	}
	
	private String emailParam(String str, Map<String,String> paramMap) {
		if (paramMap != null && !paramMap.isEmpty()) {
			for(String paramKey : paramMap.keySet()){
				String paramValue = paramMap.get(paramKey);
				str = StrUtils.replace(str, "{"+paramKey+"}", paramValue);
			}
        }
        return str;
	}
	/**
	 * 准备发送,进去发送队列
	 * @Methods Name readSend
	 * @Create In 2014年11月11日 By lee
	 * @param mailBox
	 */
	private void readSend(MailBox mailBox){
		if(mailSendTask==null){
			mailSendTask = new MailSendTask(mailForm,javaMailSender,mailBoxDao);
			new Thread(mailSendTask).start();
			List<MailBox> boxs = mailBoxDao.findBySendState(MailBox.STATE_READY);
			for(MailBox box : boxs){
				mailSendTask.addItem(box);
			}
		}else{
			mailSendTask.addItem(mailBox);
		}
	}
}

 新增一个邮件发送任务类

/**
 * 邮件发送任务
 * @ClassName: MailSendTask
 * @Description: TODO
 * @Create In 2014年11月11日 By lee
 */
public class MailSendTask implements Runnable {
	private static Log logger = LogFactory.getLog(MailSendTask.class);
	private static BlockingQueue<MailBox> calls = new LinkedBlockingQueue<MailBox>(500);
	private String mailForm = "lee";
	private JavaMailSender javaMailSender; // 邮件发送对象,采用的是spring中的实现类org.springframework.mail.javamail.JavaMailSenderImpl
	private MailBoxDao mailBoxDao;
	public MailSendTask(String mailForm, JavaMailSender javaMailSender,MailBoxDao mailBoxDao) {
		this.javaMailSender = javaMailSender;
		this.mailBoxDao = mailBoxDao;
		this.mailForm = mailForm;
	}
	@Override
	public void run() {
		logger.info("邮件发送线程启动");
        while (true) {
            try {
            	MailBox mailBox = calls.take();
            	sendMail(mailBox);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
        }
	}
	public void addItem(MailBox mailBox) {
		try {
			calls.put(mailBox);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	private void sendMail(MailBox mailBox){
		JavaMailSenderImpl senderImpl = new JavaMailSenderImpl();
		MimeMessage mimeMessage = senderImpl.createMimeMessage();
		try{
			// 设置utf-8或GBK编码,否则邮件会有乱码
			MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage, true, "utf-8");
			if (StrUtils.isNotEmpty(mailBox.getTouser())) {	//设定收件人
	            mimeMessage.setRecipients(Message.RecipientType.TO, getAddressArray(mailBox.getTouser()));
	        }
	        if (StrUtils.isNotEmpty(mailBox.getCc())) {		//设定抄送
	            mimeMessage.setRecipients(Message.RecipientType.CC, getAddressArray(mailBox.getCc()));
	        }
	        if (StrUtils.isNotEmpty(mailBox.getBcc())) {	//设定密送
	            mimeMessage.setRecipients(Message.RecipientType.BCC, getAddressArray(mailBox.getBcc()));
	        }
			
			messageHelper.setFrom(mailForm);// 发送者
			messageHelper.setSubject(mailBox.getTitle());// 主题
			// 邮件内容,注意加参数true
			messageHelper.setText(mailBox.getContent(), true);
			// 附件内容
			if (StrUtils.isNotEmpty(mailBox.getFilePath())) {
	            String[] filePaths = mailBox.getFilePath().split(";");
	
	            for (String filePath : filePaths) {
	            	File file = new File(filePath);
	                //使用MimeUtility.encodeWord()来解决附件名称的中文问题
	    			messageHelper.addAttachment(MimeUtility.encodeWord(file.getName()), file);
	            }
	        }
			javaMailSender.send(mimeMessage);
			mailBox.setSendState(MailBox.STATE_FINISH);
			mailBox.setSendTime(DateUtils.getCurrentDateTimeStr());
			mailBoxDao.save(mailBox);
		}catch(Exception e){
			logger.error("邮件发送失败");
		}
	}
	/**
	 * 组装收件地址
	 * @Methods Name getAddressArray
	 * @Create In 2014年11月10日 By lee
	 * @param addressStr
	 * @return
	 * @throws AddressException
	 */
	private InternetAddress[] getAddressArray(String addressStr) throws AddressException{
		String[] abcc = addressStr.split(";");
        InternetAddress[] adds = new InternetAddress[abcc.length];

        for (int i = 0; i < abcc.length; i++) {
        	adds[i] = new InternetAddress(abcc[i]);
        }
        return adds;
	}

 两个相关实体类

public class MailBox extends IdEntity {
	public static final int STATE_READY = 0;	//待发送
	public static final int STATE_FINISH = 1;	//已发送
	private String title;		//邮件标题
	private String content;		//	邮件内容
	private Integer sendState;	//	发送状态 0,待发 1,已发送
	private String sendTime;	//	发送时间
	private String sendNums;	//	发送次数
	private String touser;		//	收件人
	private String cc;			//	抄送人
	private String bcc;			//	密送人
	private String filePath;	//	文件路径

 

public class MailTemplate extends IdEntity {
	public static final int USED = 1;	//在用
	public static final int UNUSED = 0;	//未用
	
	private String code;		//关键字
	private String descn;		//描述
	private String title;		//模板标题
	private String content;		//模板内容

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics