關於“郵箱傳送驗證碼”介面的開發以及中間遇到的問題
阿新 • • 發佈:2021-02-05
技術標籤: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,重啟應用就好了