1. 程式人生 > 其它 >關於“郵箱傳送驗證碼”介面的開發以及中間遇到的問題

關於“郵箱傳送驗證碼”介面的開發以及中間遇到的問題

技術標籤:java

關於“郵箱傳送驗證碼”介面的開發以及中間遇到的問題

應用場景:系統開發忘記密碼功能,需要通過系統郵箱傳送驗證碼進行驗證

關於程式碼:包括了三個工具類還有一個業務處理類(工具類主要是用的之前在網上百度到的程式碼,可以搜一下去原博主主頁看)

①業務類(傳送驗證碼,設定驗證碼有效時間)

public class SendMailService extends CtrlServiceAdapter
{
  private static final OSPLogger logger = OSPLogger.getLogger(SendMailService.class);

  public Object doCtrlService(StubObject context, JParamObject po, HttpServletRequest req, HttpServletResponse resp)
    throws Exception
  {
	  Properties properties = new Properties();
	  InputStream inputStream = new BufferedInputStream (new FileInputStream(this.getClass().getResource("/").getPath()+"emailprop.properties"));
      try {
          properties.load(inputStream);
      } catch (IOException e) {
          e.printStackTrace();
      }
       String ServerHost= (String) properties.get("ServerHost");
       String ServerPort= (String) properties.get("ServerPort");
       String UserName= (String) properties.get("UserName");
       String Password= (String) properties.get("Password");
       String FromAddress= (String) properties.get("FromAddress");
      // String emailtitle= (String) properties.get("emailtitle");
	    HttpSession session = req.getSession(true);
		String attrName = "_code";
		MailSenderInfo mailInfo = new MailSenderInfo();
		mailInfo.setMailServerHost(ServerHost);
		mailInfo.setMailServerPort(ServerPort);
		mailInfo.setValidate(true);
		mailInfo.setUserName(UserName);
		mailInfo.setPassword(Password);// 郵箱密授權碼!!!
		String email=req.getParameter("email");
		mailInfo.setFromAddress(FromAddress);
		mailInfo.setToAddress(email);
		mailInfo.setSubject("郵件主題");
		String verifyCode = String.valueOf(new Random().nextInt(899999) + 100000);//驗證碼
		session.setAttribute(attrName, verifyCode);
		String context1 = "<html><head><title></title></head><body>您好<br/>您的驗證碼是:"
				+ verifyCode
				+ "<br/>此驗證碼只能使用一次,在3分鐘內有效。驗證成功則自動失效。<br/>如果您沒有進行上述操作,請忽略此郵件。";
		mailInfo.setContent(context1);
		// 發郵件
		System.setProperty("https.protocols", "TLSv1,TLSv1.1,TLSv1.2,TLSv1.3");
		SimpleMailSender sms = new SimpleMailSender();
		sms.sendHtmlMail(mailInfo);// 傳送html格式 一般用這個
		this.removeAttrbute(session, attrName);
    return null;
  }
  /**
	 * 設定3分鐘後刪除session中的驗證碼
	 * 
	 * @param session
	 * @param attrName
	 */
	private void removeAttrbute(final HttpSession session, final String attrName) {
		final Timer timer = new Timer();
		timer.schedule(new TimerTask() {
			@Override
			public void run() {
				// 刪除session中存的驗證碼
				session.removeAttribute(attrName);
				timer.cancel();
			}
		}, 3 * 60 * 1000);
	}
	
	
}

配置檔案emailprop.properties

②工具類

MailSenderInfo.java--傳送郵件需要使用的基本資訊

public class MailSenderInfo {   
    // 發郵件的伺服器的IP和埠   
    private String mailServerHost;   
    private String mailServerPort = "25";   
    // 郵件傳送者   
    private String fromAddress;   
    // 郵件接收者   
    private String toAddress;   
    // 登陸郵件傳送伺服器的使用者名稱和密碼   
    private String userName;   
    private String password;   
    // 是否需要身份驗證   
    private boolean validate = true;   
    // 郵件主題   
    private String subject;   
    // 郵件的文字內容   
    private String content;   
    // 郵件附件的檔名   
    private String[] attachFileNames;     
	private static String sslTrust = ""; //信任站點 與郵件伺服器地址相同  smtp.pansoft.com
	private static String sslEnable = "";  //是否開啟SSL加密   true
	private static String starttls = "";  //是否開啟TLS安全連線 true
	private static String socketFactoryClass = ""; //ssl的工廠類  javax.net.ssl.SSLSocketFactory
	private static String socketFactoryFallback = ""; //ssl的請求退回 一般為false
    /**  
      *	 獲得郵件會話屬性  
      */   
    public Properties getProperties(){   
      Properties p = new Properties();   
      p.put("mail.smtp.host", this.mailServerHost);   
      p.put("mail.smtp.port", this.mailServerPort);   
      p.put("mail.smtp.auth", validate ? "true" : "false");  
     // p.put("mail.smtp.auth", true);   
     //   p.put("mail.transport.protocol","smtp");
      p.put("mail.smtp.ssl.trust", this.mailServerHost);
	  p.put("mail.smtp.ssl.enable", true);
	  p.put("mail.smtp.starttls.enable", true);// 使用 STARTTLS安全連線
	  p.put("mail.smtp.starttls.required", true);// 使用 STARTTLS安全連線
	  p.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");  
	  p.put("mail.smtp.socketFactory.fallback", false);  
      p.put("mail.smtp.socketFactory.port", this.mailServerPort);  
      return p;   
    }   
    public String getMailServerHost() {   
      return mailServerHost;   
    }   
    public void setMailServerHost(String mailServerHost) {   
      this.mailServerHost = mailServerHost;   
    }  
    public String getMailServerPort() {   
      return mailServerPort;   
    }  
    public void setMailServerPort(String mailServerPort) {   
      this.mailServerPort = mailServerPort;   
    }  
    public boolean isValidate() {   
      return validate;   
    }  
    public void setValidate(boolean validate) {   
      this.validate = validate;   
    }  
    public String[] getAttachFileNames() {   
      return attachFileNames;   
    }  
    public void setAttachFileNames(String[] fileNames) {   
      this.attachFileNames = fileNames;   
    }  
    public String getFromAddress() {   
      return fromAddress;   
    }   
    public void setFromAddress(String fromAddress) {   
      this.fromAddress = fromAddress;   
    }  
    public String getPassword() {   
      return password;   
    }  
    public void setPassword(String password) {   
      this.password = password;   
    }  
    public String getToAddress() {   
      return toAddress;   
    }   
    public void setToAddress(String toAddress) {   
      this.toAddress = toAddress;   
    }   
    public String getUserName() {   
      return userName;   
    }  
    public void setUserName(String userName) {   
      this.userName = userName;   
    }  
    public String getSubject() {   
      return subject;   
    }  
    public void setSubject(String subject) {   
      this.subject = subject;   
    }  
    public String getContent() {   
      return content;   
    }  
    public void setContent(String textContent) {   
      this.content = textContent;   
    }   
}   
public class MyAuthenticator extends Authenticator{  
    String userName=null;  
    String password=null;  
       
    public MyAuthenticator(){  
    }  
    public MyAuthenticator(String username, String password) {   
        this.userName = username;   
        this.password = password;   
    }   
    protected PasswordAuthentication getPasswordAuthentication(){  
        return new PasswordAuthentication(userName, password);  
    }  
}  

SimpleMailSender.java --發郵件的工具類

public class SimpleMailSender {
	/**
	 * 以文字格式傳送郵件
	 * 
	 * @param mailInfo 待發送的郵件的資訊
	 */
	public boolean sendTextMail(MailSenderInfo mailInfo) {
		// 判斷是否需要身份認證
		MyAuthenticator authenticator = null;
		Properties pro = mailInfo.getProperties();
		if (mailInfo.isValidate()) {
			// 如果需要身份認證,則建立一個密碼驗證器
			authenticator = new MyAuthenticator(mailInfo.getUserName(), mailInfo.getPassword());
		}
		// 根據郵件會話屬性和密碼驗證器構造一個傳送郵件的session
		Session sendMailSession = Session.getDefaultInstance(pro, authenticator);
		try {
			// 根據session建立一個郵件訊息
			Message mailMessage = new MimeMessage(sendMailSession);
			// 建立郵件傳送者地址
			Address from = new InternetAddress(mailInfo.getFromAddress());
			// 設定郵件訊息的傳送者
			mailMessage.setFrom(from);
			// 建立郵件的接收者地址,並設定到郵件訊息中
			Address to = new InternetAddress(mailInfo.getToAddress());
			mailMessage.setRecipient(Message.RecipientType.TO, to);
			// 設定郵件訊息的主題
			mailMessage.setSubject(mailInfo.getSubject());
			// 設定郵件訊息傳送的時間
			mailMessage.setSentDate(new Date());
			// 設定郵件訊息的主要內容
			String mailContent = mailInfo.getContent();
			mailMessage.setText(mailContent);
			// 傳送郵件
			Transport.send(mailMessage);
			return true;
		} catch (MessagingException ex) {
			ex.printStackTrace();
		}
		return false;
	}

	/**
	 * 以HTML格式傳送郵件
	 * 
	 * @param mailInfo 待發送的郵件資訊
	 */
	public static boolean sendHtmlMail(MailSenderInfo mailInfo) {
		// 判斷是否需要身份認證
		MyAuthenticator authenticator = null;
		Properties pro = mailInfo.getProperties();
		// 如果需要身份認證,則建立一個密碼驗證器
		if (mailInfo.isValidate()) {
			authenticator = new MyAuthenticator(mailInfo.getUserName(), mailInfo.getPassword());
		}
		// 根據郵件會話屬性和密碼驗證器構造一個傳送郵件的session
		Session sendMailSession = Session.getDefaultInstance(pro, authenticator);
		try {
			// 根據session建立一個郵件訊息
			Message mailMessage = new MimeMessage(sendMailSession);
			// 建立郵件傳送者地址
			Address from = new InternetAddress(mailInfo.getFromAddress());
			// 設定郵件訊息的傳送者
			mailMessage.setFrom(from);
			// 建立郵件的接收者地址,並設定到郵件訊息中
			Address to = new InternetAddress(mailInfo.getToAddress());
			// Message.RecipientType.TO屬性表示接收者的型別為TO
			mailMessage.setRecipient(Message.RecipientType.TO, to);
			// 設定郵件訊息的主題
			mailMessage.setSubject(mailInfo.getSubject());
			// 設定郵件訊息傳送的時間
			mailMessage.setSentDate(new Date());
			// MiniMultipart類是一個容器類,包含MimeBodyPart型別的物件
			Multipart mainPart = new MimeMultipart();
			// 建立一個包含HTML內容的MimeBodyPart
			BodyPart html = new MimeBodyPart();
			// 設定HTML內容
			html.setContent(mailInfo.getContent(), "text/html; charset=utf-8");
			mainPart.addBodyPart(html);
			// 將MiniMultipart物件設定為郵件內容
			mailMessage.setContent(mainPart);
			// 傳送郵件
			Transport.send(mailMessage);
			return true;
		} catch (MessagingException ex) {
			ex.printStackTrace();
		}
		return false;
	}
}

關於應用:完成上述程式碼,並且配置介面之後就可以在windows下使用了,本來以為就沒事了,自信滿滿的上傳到了伺服器,結果不能用,接下來請看一下各式各樣的報錯........

報錯①:找不到域名,ping不通,telnet無法連線

解決:因為公司網路的限制,需要連外網獲取郵箱外網地址,並在/etc/hosts檔案里加上一行“IP地址 域名”,或者是在訪問郵箱的時候直接用IP訪問。

(改了hosts需要再重啟檢視網路狀態:systemctl status network 重啟網路:systemctl restart network)

報錯②:這個問題將配置檔案中的ServerPort換成465,重啟應用就好了