java編寫(xiě)簡(jiǎn)單的E-mail發(fā)送端程序
本文實(shí)例介紹了簡(jiǎn)單E-mail發(fā)送端程序的Java實(shí)現(xiàn)代碼,分享給大家供大家參考,具體內(nèi)容如下
在這個(gè)代碼中,有幾個(gè)注意點(diǎn)強(qiáng)調(diào)一下:
1、使用 Socket 與 SMTP 郵件服務(wù)器取得連接,注意 SMTP 服務(wù)器的主機(jī)名;
2、使用 data 命令時(shí),若寫(xiě)了 subject (主題)之后,郵件的正文部分必須與 subject 之間有一個(gè)空行,即“回車+換行”,在代碼中則是 \r\n ;
3、同樣需要將發(fā)件人的郵箱用戶名、密碼進(jìn)行 BASE64 編碼之后再傳給 SMTP 服務(wù)器;
4、程序在編譯時(shí)仍然存在警告,這是由于 sun.misc.BASE64Encoder 類是存在于 rt.jar 包中的,由于 JDK 會(huì)更新升級(jí),可能會(huì)導(dǎo)致該包中的某些類發(fā)生變化而不可用,所以編譯器會(huì)發(fā)出警告。
此外,寫(xiě)了這些代碼,也發(fā)現(xiàn)了一些問(wèn)題:
1、smtp.qq.com 和 smtp.sina.com 郵件服務(wù)器不知道為什么不能用,也就是說(shuō),當(dāng)發(fā)件人的郵箱地址是 qq 或者 sina 時(shí),這個(gè)程序不管用了,狀態(tài)應(yīng)答碼也看不懂。在我的測(cè)試當(dāng)中,只有 smtp.163.com 可以用,明明都是在官網(wǎng)查到這幾個(gè) SMTP 服務(wù)器的,怎么不能用呢?真奇怪。有哪位朋友知道的希望能告訴我,謝謝!
2、在下面的 SimpleMailSender 類中的 sendEmail() 方法中,有些重復(fù)代碼讓人感到疑惑,但是沒(méi)辦法,我暫時(shí)還弄不懂…
3、重大發(fā)現(xiàn):QQ 郵箱接收郵件的速度比 163 郵箱、sina 郵箱要快上可能有數(shù)十倍,真讓我驚訝。此外,使用 nslookup 命令查詢 smtp.qq.com 的主機(jī)名時(shí),發(fā)現(xiàn)它有好多臺(tái) SMTP 服務(wù)器,至少比 163 的 3 臺(tái)多出 5 臺(tái),騰訊真夠強(qiáng)大;
4、雖然說(shuō)寫(xiě)了這個(gè)程序可以惡意地不停給某個(gè)郵箱發(fā)郵件,但是我發(fā)現(xiàn),當(dāng)我用一個(gè) sina 郵箱連續(xù)發(fā)送了幾十封郵件給固定的另一個(gè)郵箱之后,該 sina 郵箱再想發(fā)郵件就會(huì)被拒絕,小心喲。
代碼如下:
// 郵件 class E_Mail { String from; String to; String subject; String content; String userName; String pwd; public E_Mail(String from, String to, String subject, String content, String userName, String pwd) { this.from = from; this.to = to; this.subject = subject; this.content = content; this.userName = this.toBASE64(userName); this.pwd = this.toBASE64(pwd); } /** * 在 E_Mail 類中進(jìn)行用戶名、密碼的轉(zhuǎn)碼工作 */ private String toBASE64(String str) { return (new sun.misc.BASE64Encoder().encode(str.getBytes())); } } // 簡(jiǎn)單的郵件發(fā)送端類,實(shí)現(xiàn)發(fā)送功能 public class SimpleMailSender { private String smtpServer; private int port = 25; private Socket socket; BufferedReader br; PrintWriter pw; /** * 根據(jù)發(fā)件人的郵箱地址確定SMTP郵件服務(wù)器 */ private void initServer(String from) { if(from.contains("@163")) { this.smtpServer = "smtp.163.com"; }else if(from.contains("@126")) { this.smtpServer = "smtp.126.com"; }else if(from.contains("@sina")) { this.smtpServer = "smtp.sina.com"; }else if(from.contains("@qq")) { this.smtpServer = "smtp.qq.com"; } } public void sendEmail(E_Mail email) { try { this.initServer(email.from); this.socket = new Socket(smtpServer, port); this.br = this.getReader(socket); this.pw = this.getWriter(socket); // 開(kāi)始組裝發(fā)送郵件的命令序列 send_Receive(null); // 接收連接SMTP服務(wù)器成功的信息 send_Receive("ehlo hao"); send_Receive("auth login"); send_Receive(email.userName); send_Receive(email.pwd); send_Receive("mail from:<" + email.from + ">"); send_Receive("rcpt to:<" + email.to + ">"); send_Receive("data"); // 郵件內(nèi)容 pw.println("from:" + email.from); pw.println("to:" + email.to); // 主題與正文之間一定要空一行,即加上"\r\n" pw.println("subject:" + email.subject + "\r\n"); // 在控制臺(tái)打印郵件內(nèi)容 System.out.println("from:" + email.from); System.out.println("to:" + email.to); System.out.println("subject:" + email.subject + "\r\n"); System.out.println(email.content); // 郵件正文 pw.println(email.content); // 一定記得正文以"."結(jié)束 send_Receive("."); send_Receive("quit"); } catch (IOException e) { e.printStackTrace(); } finally { try { if (socket != null) socket.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * 每發(fā)送一條命令,必須在命令后面加上"\r\n", * 則同時(shí)打印出smtp郵件服務(wù)器的相應(yīng)狀態(tài)碼 * @param command */ private void send_Receive(String command) throws IOException{ if(command != null) { // 向SMTP郵件服務(wù)器發(fā)送命令,一定要記得加上"\r\n" pw.print(command + "\r\n"); pw.flush(); System.out.println("用戶 >> " + command); } char [] response = new char[1024]; br.read(response); System.out.println(response); } /** * 獲取 Socket 的輸出流 */ private PrintWriter getWriter(Socket socket) throws IOException { OutputStream socketOut = socket.getOutputStream(); return new PrintWriter(socketOut, true); } /** * 獲取 Socket 的輸入流 */ private BufferedReader getReader(Socket socket) throws IOException { InputStream socketIn = socket.getInputStream(); return new BufferedReader(new InputStreamReader(socketIn)); } // 測(cè)試 public static void main(String[] args) { new MailSenderGUI(); } } // 郵件發(fā)送程序界面 class MailSenderGUI extends JFrame implements ActionListener { private JLabel userNameLabel; private JTextField userNameField; private JLabel pwdLabel; private JPasswordField pwdField; private JLabel fromLabel; private JTextField fromField; private JLabel toLabel; private JTextField toField; private JLabel subjectLabel; private JTextField subjectField; private JLabel contentLabel; private JTextArea contentArea; private JButton sendBtn; private JButton cancelBtn; private E_Mail email; private SimpleMailSender mailSender; public MailSenderGUI() { this.init(); this.mailSender = new SimpleMailSender(); } private void init() { this.fromLabel = new JLabel("發(fā)件人郵箱地址:"); this.fromField = new JTextField(25); this.userNameLabel = new JLabel("用戶名:"); this.userNameField = new JTextField(25); this.pwdLabel = new JLabel("密碼:"); this.pwdField = new JPasswordField(25); this.toLabel = new JLabel("收件人郵箱地址:"); this.toField = new JTextField(25); this.subjectLabel = new JLabel("郵件主題:"); this.subjectField = new JTextField(20); this.contentLabel = new JLabel("郵件正文:"); this.contentArea = new JTextArea(15, 20); this.setTitle("螞蟻-->簡(jiǎn)單郵件發(fā)送器"); this.setBounds(200, 30, 500, 500); this.setLayout(new BorderLayout()); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); this.sendBtn = new JButton("發(fā)送"); this.cancelBtn = new JButton("重置"); this.sendBtn.addActionListener(this); this.cancelBtn.addActionListener(this); JPanel upPanel = new JPanel(new GridLayout(6, 2, 5, 5)); upPanel.add(fromLabel); upPanel.add(fromField); upPanel.add(userNameLabel); upPanel.add(userNameField); upPanel.add(pwdLabel); upPanel.add(pwdField); upPanel.add(toLabel); upPanel.add(toField); upPanel.add(subjectLabel); upPanel.add(subjectField); upPanel.add(contentLabel); this.add(upPanel, BorderLayout.NORTH); this.add(contentArea, BorderLayout.CENTER); JPanel downPanel = new JPanel(new FlowLayout(FlowLayout.CENTER)); downPanel.add(sendBtn, BorderLayout.SOUTH); downPanel.add(cancelBtn, BorderLayout.SOUTH); this.add(downPanel, BorderLayout.SOUTH); } @Override public void actionPerformed(ActionEvent e) { if (e.getSource() == this.sendBtn) { this.email = new E_Mail( this.fromField.getText(), this.toField.getText(), this.subjectField.getText(), this.contentArea.getText(), this.userNameField.getText(), new String(this.pwdField.getPassword()) ); this.mailSender.sendEmail(this.email); } else if (e.getSource() == this.cancelBtn) { this.fromField.setText(null); this.toField.setText(null); this.subjectField.setText(null); this.contentArea.setText(null); } } }
以上就是java編寫(xiě)簡(jiǎn)單E-mail發(fā)送端程序的全部代碼,希望對(duì)大家的學(xué)習(xí)有所幫助。
相關(guān)文章
SpringBoot部署到外部Tomcat無(wú)法注冊(cè)到Nacos服務(wù)端的解決思路
這篇文章主要介紹了SpringBoot部署到外部Tomcat無(wú)法注冊(cè)到Nacos服務(wù)端,本文給大家分享完美解決思路,結(jié)合實(shí)例代碼給大家講解的非常詳細(xì),需要的朋友可以參考下2023-03-03Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(19)
下面小編就為大家?guī)?lái)一篇Java基礎(chǔ)的幾道練習(xí)題(分享)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧,希望可以幫到你2021-07-07java調(diào)用WebService服務(wù)的四種方法總結(jié)
WebService是一種跨編程語(yǔ)言、跨操作系統(tǒng)平臺(tái)的遠(yuǎn)程調(diào)用技術(shù),已存在很多年了,很多接口也都是通過(guò)WebService方式來(lái)發(fā)布的,下面這篇文章主要給大家介紹了關(guān)于java調(diào)用WebService服務(wù)的四種方法,需要的朋友可以參考下2021-11-11Java如何使用spire進(jìn)行word文檔的替換詳解
創(chuàng)作一份文案經(jīng)常會(huì)高頻率地使用某些詞匯,如地名、人名、人物職位等,若表述有誤,就需要整體撤換,下面這篇文章主要給大家介紹了關(guān)于Java如何使用spire進(jìn)行word文檔的替換的相關(guān)資料,需要的朋友可以參考下2023-01-01Mybatis把返回結(jié)果封裝成map類型的實(shí)現(xiàn)
本文主要介紹了Mybatis把返回結(jié)果封裝成map類型的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03SPRING BOOT啟動(dòng)命令參數(shù)及源碼詳析
這篇文章主要給大家介紹了關(guān)于SPRING BOOT啟動(dòng)命令參數(shù)及源碼分析的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用SPRING BOOT具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12Java開(kāi)發(fā)必備知識(shí)之?dāng)?shù)組詳解
數(shù)組對(duì)于每一門(mén)編程語(yǔ)言來(lái)說(shuō)都是重要的數(shù)據(jù)結(jié)構(gòu)之一,當(dāng)然不同語(yǔ)言對(duì)數(shù)組的實(shí)現(xiàn)及處理也不盡相同.本篇文章為大家整理了Java最全關(guān)于數(shù)組的知識(shí)點(diǎn),并給出其對(duì)應(yīng)的代碼,需要的朋友可以參考下2021-06-06