發送郵件失敗提示validity check failed 處理

前幾天發現發送郵件服務失效了,通過查看日誌發現異常提示爲Exception reading response 。 在本地開始調試排查原因。之前發送代碼如下:

public static void sendEmail(Map<String, Object> map) {

		/**
		 * 參數配置--裝信封寫地址
		 */
		Properties prop = new Properties();// 配置參數類
		prop.setProperty("mail.transport.protocol", "smtp");// 參數一:使用電子郵件協議smtp
		prop.setProperty("mail.smtp.host", EmailSMTPHost); // 參數二:協議所在服務器
		prop.setProperty("mail.smtp.auth", "true");// 參數三:需要請求認證改爲true 不然553報錯
		/**
		 * 根據配置創建會話對象, 用於和郵件服務器交互---檢查地址是否能對打個電話問問
		 */
		final String smtpPort = "465";
		prop.setProperty("mail.smtp.port", smtpPort);
		prop.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
		prop.setProperty("mail.smtp.socketFactory.fallback", "false");
		prop.setProperty("mail.smtp.socketFactory.port", smtpPort);
		Session session = null;
		Transport transport = null;
		try {
			session = Session.getDefaultInstance(prop);// 將參數與會話結合
			// session.setDebug(true);// 這個是開啓debug 方便查看
			/**
			 * 郵件封裝
			 */
			MimeMessage message = createMimeMessage(session, EmailAccount, map);
			/**
			 * 郵遞員
			 */
			transport = session.getTransport();
			transport.connect(EmailAccount, EmailPassword);// 敲門開門
			transport.sendMessage(message, message.getAllRecipients());// 送到對方手裏
			System.err.println("發送完畢");
		} catch (NoSuchProviderException e) {
			logger.error(e.getMessage());
		} catch (MessagingException e) {
			logger.error(e.getMessage());
		} catch (Exception e) {
			logger.error(e.getMessage());
		} finally {
			if (transport != null) {
				try {
					transport.close();
				} catch (MessagingException e) {
					logger.error(e.getMessage());
				}
			}
		}
	}

由於之前一直沒問題,問題肯定出現在郵件服務器,但是通過telnet 發送郵件測試是沒有問題,所以問題出現在java 代碼中通過設置session.setDebug(true); 打印詳細的日誌信息。如下:

DEBUG: setDebug: JavaMail version 1.4ea
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc]
DEBUG SMTP: useEhlo true, useAuth true
DEBUG SMTP: trying to connect to host “smtp.cailian.net”, port 465, isSSL false
DEBUG SMTP: exception reading response: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: validity check failed
15:30:00.252 [main] ERROR com.vtax.utils.MailSend - Exception reading response

通過異常提示我們知道了有效檢查性失敗 是因爲請求證書過期,爲啥我們之前麼有 是因爲stmp 沒有開啓ssl,所以只有賬戶密碼對就可以發送郵件。現在開啓後更嚴格1要不你有對應證書2、就是信任所有證書。我們https 請求時候也有類似問題。通過查閱資料我使用的mail jar 是1.4 不加jar 前提需要升級,目前是使用jar 1.4.5 他實現了MailSSLSocketFactory通過設置該類的屬性trustAllHosts 同時開啓mail.smtp.ssl.enable = true 即可。完善後代碼如下:

	public static void sendEmail(Map<String, Object> map) {
		/**
		 * 參數配置--裝信封寫地址
		 */
		Properties prop = new Properties();// 配置參數類
		prop.setProperty("mail.transport.protocol", "smtp");// 參數一:使用電子郵件協議smtp
		prop.setProperty("mail.smtp.host", EmailSMTPHost); // 參數二:協議所在服務器
		prop.setProperty("mail.smtp.auth", "true");// 參數三:需要請求認證改爲true 不然553報錯
		/**
		 * 根據配置創建會話對象, 用於和郵件服務器交互---檢查地址是否能對打個電話問問
		 */
		final String smtpPort = "465";
		MailSSLSocketFactory sf = null;
		      try {
		            sf = new MailSSLSocketFactory();
		            sf.setTrustAllHosts(true);
		      } catch (GeneralSecurityException e1) {
		            e1.printStackTrace();
		      }
		prop.setProperty("mail.smtp.port", smtpPort);
		prop.setProperty("mail.smtp.ssl.enable", "true");
		prop.put("mail.smtp.ssl.socketFactory", sf);
		prop.setProperty("mail.smtp.socketFactory.port", smtpPort);
		
		Session session = null;
		Transport transport = null;
		try {
			session = Session.getDefaultInstance(prop);// 將參數與會話結合
			session.setDebug(true);// 這個是開啓debug 方便查看
			/**
			 * 郵件封裝
			 */
			MimeMessage message = createMimeMessage(session, EmailAccount, map);
			/**
			 * 郵遞員
			 */
			transport = session.getTransport();
			transport.connect(EmailSMTPHost,EmailAccount, EmailPassword);// 敲門開門
			transport.sendMessage(message, message.getAllRecipients());// 送到對方手裏
			System.err.println("發送完畢");
		} catch (NoSuchProviderException e) {
			logger.error(e.getMessage(),e);
		} catch (MessagingException e) {
			logger.error(e.getMessage());
		} catch (Exception e) {
			logger.error(e.getMessage());
		} finally {
			if (transport != null) {
				try {
					transport.close();
				} catch (MessagingException e) {
					logger.error(e.getMessage());
				}
			}
		}
	}

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章