发送邮件增加同步锁

来源:互联网 发布:360软件助手 编辑:程序博客网 时间:2024/06/13 03:40
import java.util.Calendar;
import java.util.Date;
import java.util.Properties;
import javax.mail.Address;
import javax.mail.Authenticator;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

import xxxxx.adp.core.exception.BizException;
import xxxxx.adp.entity.sys.SysUser;
import xxxxx.adp.service.sys.SysUserService;


/**
 *  本类版本:version 1.0
 */
public class SendE_mail extends Authenticator {
    String mailServerHost; // 发送邮件的服务器的IP
    String fromE_mail;//发送邮件的邮箱
    String passwordToFromE_mail;//发送邮件邮箱对应的邮箱密码
    private final static int email_time_interval = commonProperty.getEmail_time_interval();
    private final static int email_times = commonProperty.getEmail_times();
    public SendE_mail() {
        
    }
    public SendE_mail(String fromE_mail, String passwordToE_mail) {
        this.fromE_mail = fromE_mail;
        this.passwordToFromE_mail = passwordToE_mail;
    }
    protected PasswordAuthentication getPasswordAuthentication(){
        return new PasswordAuthentication(fromE_mail, passwordToFromE_mail);
    }
    /**
     * 本方法作用:获得邮件会话属性
     * @param fromE_mail 发送邮件的邮箱
     * @param shell Shell类型的参数
     * @return 返回Properties类型的对象
     */
    public Properties getProperties(String fromE_mail){
      Properties p = new Properties();
     if (fromE_mail.endsWith("@126.com")) {
        mailServerHost="smtp.126.com";//适用于发送的地址为xxx@126.com
      } else if (fromE_mail.endsWith("@163.com")) {
        mailServerHost="smtp.163.com";//适用于发送的地址为xxx@163.com
      }else if(fromE_mail.endsWith("@qq.com")){
          mailServerHost="smtp.qq.com";//适用于发送的地址为xxx@qq.com  
      }else{
          System.out.println("您发送邮件使用的邮箱地址无效,请使用163或126或者qq的邮箱发送邮件");//标记2
      }

      p.put("mail.smtp.host", "xxxxx");
      p.put("mail.smtp.port", "25");
      p.put("mail.smtp.starttls.enable", "true");
      p.put("mail.smtp.auth", "true");
      return p;
    }
    /**
     * 本方法作用:以HTML格式发送邮件
     * @param fromE_mail 发送邮件的邮箱
     * @param passwordToFromE_mail 发送邮件邮箱对应的邮箱密码
     * @param toE_mail 指明要将邮件发到哪个邮箱中
     * @param theme 发送邮件的主题
     * @param messageContent 发送邮件的html内容
     * @return 邮件发送成功返回true,否则返回false
     */
/*    public boolean sendHtmlMail(String fromE_mail, String passwordToFromE_mail,String toE_mail,String theme,String messageContent){
          boolean flag=false;
          fromE_mail=fromE_mail.toLowerCase();//将fromE_mail中的所有字符都转换为小写
          Properties pro =new SendE_mail().getProperties(fromE_mail);
          SendE_mail sendE_mail = new SendE_mail(fromE_mail, passwordToFromE_mail);  // 由于需要身份认证,所以则创建一个密码验证器
          Session sendMailSession = Session.getDefaultInstance(pro,sendE_mail); // 根据邮件会话属性和密码验证器构造一个发送邮件的session
          try {
              Message mailMessage = new MimeMessage(sendMailSession);  // 根据session创建一个邮件消息
              Address from = new InternetAddress(fromE_mail); // 创建邮件发送者地址
              mailMessage.setFrom(from); // 设置邮件消息的发送者
              Address to = new InternetAddress(toE_mail); // 创建邮件的接收者地址
              mailMessage.setRecipient(Message.RecipientType.TO,to); // 将邮件接收者的地址设置到邮件消息中 ,Message.RecipientType.TO属性表示接收者的类型为TO
              mailMessage.setSubject(theme); // 设置邮件消息的主题
              mailMessage.setSentDate(new Date()); // 设置邮件消息发送的时间
              Multipart mainPart = new MimeMultipart(); // MineMultipart类是一个容器类,包含MimeBodyPart类型的对象
              BodyPart html = new MimeBodyPart(); // 创建一个包含HTML内容的MimeBodyPart
              html.setContent(messageContent, "text/html; charset=UTF-8"); // 设置发送的html内容
              mainPart.addBodyPart(html);
              mailMessage.setContent(mainPart); // 将MimeMultipart对象设置为邮件内容
              Transport.send(mailMessage); // 发送邮件
              //System.out.println("以HTML格式发送邮件成功!");
              flag=true;
          } catch (MessagingException ex) {
              ex.printStackTrace();
              flag=false;
          }
          return flag;
    }*/
    
public static  void sendMail(final String fromE_mail, final String passwordToFromE_mail,final String toE_mail,final String theme,final String messageContent,final Date emailTime,final Integer userId,final SysUserService sysUserService){
        
        new Thread(new Runnable() {
            @Override
            public void run() {
                //发送逻辑
            
                try {
                    sendMailByAsynchronous(  fromE_mail,  passwordToFromE_mail, toE_mail,theme, messageContent, emailTime,userId,sysUserService);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                
            }
        } ).start();
        
    }
public static synchronized void  sendMailByAsynchronous(String fromE_mail, String passwordToFromE_mail,String toE_mail,String theme,String messageContent,Date emailTime,Integer userId,SysUserService sysUserService) throws Exception{
    SysUser sysUser = sysUserService.getUser(userId);
    sysUser.setEmailTime(new Date());
    if(emailTime != null && emailTime.toString().length() > 0){
          /** 是邮件在两分钟内无法重复发送,阻止邮件炸弹 **/
          Date date = new Date();
          Calendar cal=Calendar.getInstance();
          cal.setTime(emailTime);
          cal.add(Calendar.SECOND, email_time_interval);
          Date nowTime = cal.getTime();
          if(date.before(nowTime) || (sysUser.getLimitNumber() != null&&sysUser.getLimitNumber() > email_times)){
              System.out.println("请在"+email_time_interval+"s后重发");
              try {
                sysUserService.updateUser(sysUser);
            } catch (BizException e) {
                e.printStackTrace();
            }
              return;
          }
      }
      String times = RedisUtil.getValue("Email-login-number-"+sysUser.getLoginName());
      System.out.println(times);
      if(times == null || Integer.parseInt(times)<=4){
          if(times == null){
              RedisUtil.setValue("Email-login-number-"+sysUser.getLoginName(), "1");
          }else{
              RedisUtil.setValue("Email-login-number-"+sysUser.getLoginName(), String.valueOf((Integer.parseInt(times)+1)));
          }
          boolean flag=false;
          fromE_mail=fromE_mail.toLowerCase();//将fromE_mail中的所有字符都转换为小写
          Properties pro =new SendE_mail().getProperties(fromE_mail);
          SendE_mail sendE_mail = new SendE_mail(fromE_mail, passwordToFromE_mail);  // 由于需要身份认证,所以则创建一个密码验证器
          Session sendMailSession = Session.getDefaultInstance(pro,sendE_mail); // 根据邮件会话属性和密码验证器构造一个发送邮件的session
          try {
              Message mailMessage = new MimeMessage(sendMailSession);  // 根据session创建一个邮件消息
              Address from = new InternetAddress(fromE_mail); // 创建邮件发送者地址
              mailMessage.setFrom(from); // 设置邮件消息的发送者
              Address to = new InternetAddress(toE_mail); // 创建邮件的接收者地址
              mailMessage.setRecipient(Message.RecipientType.TO,to); // 将邮件接收者的地址设置到邮件消息中 ,Message.RecipientType.TO属性表示接收者的类型为TO
              mailMessage.setSubject(theme); // 设置邮件消息的主题
              mailMessage.setSentDate(new Date()); // 设置邮件消息发送的时间
              Multipart mainPart = new MimeMultipart(); // MineMultipart类是一个容器类,包含MimeBodyPart类型的对象
              BodyPart html = new MimeBodyPart(); // 创建一个包含HTML内容的MimeBodyPart
              html.setContent(messageContent, "text/html; charset=UTF-8"); // 设置发送的html内容
              mainPart.addBodyPart(html);
              mailMessage.setContent(mainPart); // 将MimeMultipart对象设置为邮件内容
              Transport.send(mailMessage); // 发送邮件
              //System.out.println("以HTML格式发送邮件成功!");
              flag=true;
              if(sysUser.getLimitNumber() == null){
                  sysUser.setLimitNumber(1);
              }else{
                  sysUser.setLimitNumber(sysUser.getLimitNumber()+1);
              }
              sysUserService.updateUser(sysUser);
          } catch (MessagingException ex) {
              ex.printStackTrace();
              flag=false;
          }
      }
    
      
}

}






//===================================



import java.util.Date;

import xxxx.adp.service.sys.SysUserService;

public class MyThreadTest extends Thread{
    
    private String fromE_mail;
    
    private String passwordToFromE_mail;
    
    private String toE_mail;
    
    private String theme;
    
    private String messageContent;
    
    private Date emailTime;
    
    private Integer userId;
    
    private SysUserService sysUserService;
    
    
    public MyThreadTest(String fromE_mail, String passwordToFromE_mail, String toE_mail, String theme,
            String messageContent, Date emailTime, Integer userId, SysUserService sysUserService) {
        super();
        this.fromE_mail = fromE_mail;
        this.passwordToFromE_mail = passwordToFromE_mail;
        this.toE_mail = toE_mail;
        this.theme = theme;
        this.messageContent = messageContent;
        this.emailTime = emailTime;
        this.userId = userId;
        this.sysUserService = sysUserService;
    }



    @Override
    public void run() {
        SendE_mail sendEmail = new SendE_mail();
        try {
            sendEmail.sendMailByAsynchronous(  fromE_mail,  passwordToFromE_mail, toE_mail,theme, messageContent, emailTime,userId,sysUserService);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}




//=============================

Controller方法里

Thread thread = new MyThreadTest(fromE_mail, passwordToFromE_mail,sysUser.getEmail(), emailTitle, emailContent,sysUser.getEmailTime(),sysUser.getUserId(),sysUserService);
         thread.start();