使用Apache Commons Net SMTP以Java(和Android)发送邮件:STARTTLS,SSL
最近我正在做一個Android實驗,我想使用SMTP服務器通過android應用程序通過身份驗證和加密來發送電子郵件。
好吧, 我發現Android上的javax.mail并不是一個很好的選擇 ,因為它取決于awt類(我猜是傳統); 有些人試圖對其進行調整,以使您不需要整個awt軟件包 ,但我在此方面收效甚微。 更不用說那些人幾年前自己重構了Android的javax.mail,沒有任何維護。
我想到的另一個選擇是重新使用Apache Commons Net : 由于該社區向原始SMTP客戶端添加了SMTPSClient和AuthenticatingSMTPClient ( 并為SSL和身份驗證應用了我的一點補丁 ),因此您可以將該庫嵌入Android應用程序(無需傳遞依賴項)以在安全層上使用身份驗證發送郵件。 ( 這篇文章實際上激發了我的靈感 ,但是它使用的是Apache Commons Net的舊版本,而使用3.3則不再需要這樣做)
SMTP身份驗證和具有Commons Net的STARTTLS
通常,用于此問題的端口是25或備用587端口:您通過普通連接連接到SMTP服務器,要求提供可用的命令,如果支持STARTTLS,則使用它,其余的通信將被加密。
讓我們以gmail為例,因為smtp.gmail.com支持身份驗證和STARTTLS
public void sendEmail() throws Exception { String hostname = "smtp.gmail.com";int port = 587;String password = "gmailpassword";String login = "account@gmail.com";String from = login;String subject = "subject" ;String text = "message";AuthenticatingSMTPClient client = new AuthenticatingSMTPClient();try {String to = "recipient@email.com";// optionally set a timeout to have a faster feedback on errorsclient.setDefaultTimeout(10 * 1000);// you connect to the SMTP serverclient.connect(hostname, port);// you say ehlo and you specify the host you are connecting from, could be anythingclient.ehlo("localhost");// if your host accepts STARTTLS, we're good everything will be encrypted, otherwise we're done hereif (client.execTLS()) {client.auth(AuthenticatingSMTPClient.AUTH_METHOD.LOGIN, login, password);checkReply(client);client.setSender(from);checkReply(client);client.addRecipient(to);checkReply(client);Writer writer = client.sendMessageData();if (writer != null) {SimpleSMTPHeader header = new SimpleSMTPHeader(from, to, subject);writer.write(header.toString());writer.write(text);writer.close();if(!client.completePendingCommand()) {// failurethrow new Exception("Failure to send the email "+ client.getReply() + client.getReplyString());}} else {throw new Exception("Failure to send the email "+ client.getReply() + client.getReplyString());}} else {throw new Exception("STARTTLS was not accepted "+ client.getReply() + client.getReplyString());}} catch (Exception e) {throw e;} finally {client.logout();client.disconnect();}}private static void checkReply(SMTPClient sc) throws Exception {if (SMTPReply.isNegativeTransient(sc.getReplyCode())) {throw new Exception("Transient SMTP error " + sc.getReply() + sc.getReplyString());} else if (SMTPReply.isNegativePermanent(sc.getReplyCode())) {throw new Exception("Permanent SMTP error " + sc.getReply() + sc.getReplyString());}這里沒有什么可添加的,當然,如果您使用自己的異常類,則可以優化異常處理。
帶有Commons Net的SMTP身份驗證和SSL
某些SMTP服務器配置為僅接受“ a到z SSL”:您必須在向服務器發出任何命令之前確保通信的安全; 通常使用的端口是465。
讓我們以LaPoste.net示例(法語帖子提供的免費電子郵件帳戶)為例:
public void sendEmail() throws Exception { String hostname = "smtp.laposte.net";int port = 465;String password = "password";String login = "firstname.lastname";String from = login + "@laposte.net";String subject = "subject" ;String text = "message";// this is the important part : you tell your client to connect using SSL right awayAuthenticatingSMTPClient client = new AuthenticatingSMTPClient("TLS",true);try {String to = "anthony.dahanne@gmail.com";// optionally set a timeout to have a faster feedback on errorsclient.setDefaultTimeout(10 * 1000);client.connect(hostname, port);client.ehlo("localhost");client.auth(AuthenticatingSMTPClient.AUTH_METHOD.LOGIN, login, password);checkReply(client);client.setSender(from);checkReply(client);client.addRecipient(to);checkReply(client);Writer writer = client.sendMessageData();if (writer != null) {SimpleSMTPHeader header = new SimpleSMTPHeader(from, to, subject);writer.write(header.toString());writer.write(text);writer.close();if(!client.completePendingCommand()) {// failurethrow new Exception("Failure to send the email "+ client.getReply() + client.getReplyString());}} else {throw new Exception("Failure to send the email "+ client.getReply() + client.getReplyString());}} catch (Exception e) {throw e;} finally {client.logout();client.disconnect();}我在這里沒有重復checkReply()方法,因為兩個代碼段都相同。 您會注意到,立即使用SSL意味著您不必檢查execTls()響應(實際上,如果這樣做,它將無法正常工作)。
包起來
就是這樣 如果要使這些示例在您的環境中工作,則可以將apache commons net 3.3 jar添加到您的類路徑中
如果您使用的是Maven,請添加依賴項:
<dependency><groupid>commons-net</groupid><artifactid>commons-net</artifactid><version>3.3</version> </dependency>如果您將Gradle用于Android項目,則還可以使用以下build.gradle文件:
buildscript {repositories {mavenCentral()}dependencies {classpath 'com.android.tools.build:gradle:0.4.2'} } apply plugin: 'android'repositories {mavenCentral() }dependencies {compile fileTree(dir: 'libs', include: '*.jar'), 'commons-net:commons-net:3.3' }android {compileSdkVersion 17buildToolsVersion "17.0.0"sourceSets {main {manifest.srcFile 'AndroidManifest.xml'java.srcDirs = ['src']resources.srcDirs = ['src']aidl.srcDirs = ['src']renderscript.srcDirs = ['src']res.srcDirs = ['res']assets.srcDirs = ['assets']}instrumentTest.setRoot('tests')} } 請享用 !
翻譯自: https://www.javacodegeeks.com/2013/11/sending-a-mail-in-java-and-android-with-apache-commons-net-smtp-starttls-ssl.html
總結
以上是生活随笔為你收集整理的使用Apache Commons Net SMTP以Java(和Android)发送邮件:STARTTLS,SSL的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 存款保险制度50万包括利息吗?
- 下一篇: 理财产品的预期收益率与业绩基准的区别