欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

501 Command "HELO" requires an argument問題的解決方法

 更新時間:2013年08月30日 09:07:30   作者:  
換一個windows服務器,發(fā)現(xiàn)就沒這樣的問題,僅在一臺Linux服務器上可以重現(xiàn),直觀感覺就是這臺Linux服務器某些配置有問題

場景描述:
保存郵箱配置時自動探測郵箱配置參數(shù)是否正確,結(jié)果發(fā)現(xiàn)在探測SMTP時,系統(tǒng)報出如下異常:

復制代碼 代碼如下:

javax.mail.MessagingException: 501 Command "HELO" requires an argument
        at com.sun.mail.smtp.SMTPTransport.issueCommand(SMTPTransport.java:1363)
        at com.sun.mail.smtp.SMTPTransport.helo(SMTPTransport.java:838)
        at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:375)
        at javax.mail.Service.connect(Service.java:275)

但是換一個windows服務器,發(fā)現(xiàn)就沒這樣的問題,僅在一臺Linux服務器上可以重現(xiàn),直觀感覺就是這臺Linux服務器某些配置有問題。

排查步驟
1. 找一臺同樣操作系統(tǒng)的Linux服務器,驗證郵箱配置,ok,排除Linux操作系統(tǒng)特殊性的問題
2. 直接在Linux服務器上使用telnet連接對端郵件服務器的SMTP端口,OK,排除該服務器的網(wǎng)絡問題
3. 查找HELO指令解釋
復制代碼 代碼如下:

HELO
-- Initiates a conversation with the mail server. When using this command you can specify your domain name so that the mail server knows who you are. For example, HELO mailhost2. cf.ac.uk.

發(fā)現(xiàn)HELO指令后面需要跟一個發(fā)起者的主機名,告訴SMTP服務器這個消息來源是哪里。
再看異常信息是"501 Command "HELO" requires an argument",很明顯,程序在跟SMTP SERVER交互過程中沒有傳遞源主機域名。

4. 查看JAVA MAIL源碼
查找HELO指令,如下:

復制代碼 代碼如下:

        /**
         * Issue the <code>HELO</code> command.
         *
         * @param domain
         *            our domain
         *
         * @since JavaMail 1.4.1
         */
        protected void helo(String domain) throws MessagingException {
                if (domain != null)
                        issueCommand("HELO " + domain, 250);
                else
                        issueCommand("HELO", 250);
        }

查找helo方法在哪里被調(diào)用,看看domain如何被傳遞過來的
復制代碼 代碼如下:

                if (useEhlo)
                        succeed = ehlo(getLocalHost());
                if (!succeed)
                        helo(getLocalHost());

順理成章,接著找getLocalHost()方法,定義如下:
復制代碼 代碼如下:

        /**
         * Get the name of the local host, for use in the EHLO and HELO commands.
         * The property mail.smtp.localhost overrides mail.smtp.localaddress, which
         * overrides what InetAddress would tell us.
         */
        public synchronized String getLocalHost() {
                try {
                        // get our hostname and cache it for future use
                        if (localHostName == null || localHostName.length() <= 0)
                                localHostName = session.getProperty("mail." + name + ".localhost");
                        if (localHostName == null || localHostName.length() <= 0)
                                localHostName = session.getProperty("mail." + name+ ".localaddress");
                        if (localHostName == null || localHostName.length() <= 0) {
                                InetAddress localHost = InetAddress.getLocalHost();
                                localHostName = localHost.getHostName();
                                // if we can't get our name, use local address literal
                                if (localHostName == null)
                                        // XXX - not correct for IPv6
                                        localHostName = "[" + localHost.getHostAddress() + "]";
                        }
                } catch (UnknownHostException uhex) {
                }
                return localHostName;
        }

可以看到hostname的獲取可以通過當前連接的session屬性中獲取,也可以從當前服務器的hosts配置中獲取,而我們程序是沒有在session中設置hostname的,因此原因肯定在于該臺Linux服務器的hosts文件被修改,造成JAVA程序無法自動獲得localhostName。

5. 查看/etc/hosts文件,情況如下:

復制代碼 代碼如下:

127.0.0.1              localhost.localdomain localhost
::1             localhost6.localdomain6 localhost6

簡單的將hosts文件修改如下:
復制代碼 代碼如下:

127.0.0.1       localhost
::1             localhost6.localdomain6 localhost6

6. 重新測試,問題解決了。
其實,這種情況也可以通過程序避免,即在session連接中加入當前服務器的hostname屬性,程序示例:
復制代碼 代碼如下:

        public static void main(String[] args) {
                try {
                        int smtpport = 25;
                        String smtpserver = "219.147.xxx.xxx";
                        Properties prop = System.getProperties();
                        prop.put("mail.smtp.auth", "true");
                        prop.put("mail.smtp.localhost", "myMailServer");
                        Session mailSession = Session.getInstance(prop, null);
                        Transport transport = mailSession.getTransport("smtp");
                        transport.connect(smtpserver,smtpport, "username", "password");
                        System.out.println("connect ok");
                        transport.close();
                } catch (AuthenticationFailedException en) {
                        en.printStackTrace();
                        System.out.println("smtp服務器連接失敗,請檢查輸入信息是否正確");
                } catch (NoSuchProviderException e) {
                        e.printStackTrace();
                        System.out.println("smtp服務器連接失敗,請檢查輸入信息是否正確");
                } catch (MessagingException e) {
                        e.printStackTrace();
                        System.out.println("smtp服務器連接失敗,請檢查輸入信息是否正確");
                }
        }

相關(guān)文章

  • Java實現(xiàn)的時間戳與date對象相互轉(zhuǎn)換功能示例

    Java實現(xiàn)的時間戳與date對象相互轉(zhuǎn)換功能示例

    這篇文章主要介紹了Java實現(xiàn)的時間戳與date對象相互轉(zhuǎn)換功能,結(jié)合具體實例形式分析了java日期與時間戳類型的表示與轉(zhuǎn)換相關(guān)操作技巧,需要的朋友可以參考下
    2017-06-06
  • java selenium教程之selenium詳細介紹

    java selenium教程之selenium詳細介紹

    本文主要介紹Java selenium,這里整理了selenium的一些基本資料,此軟件主要用于Web UI自動測試框架,有興趣的同學可以看一下
    2016-08-08
  • JavaWeb中Servlet的生命周期及線程安全問題詳解

    JavaWeb中Servlet的生命周期及線程安全問題詳解

    這篇文章主要介紹了JavaWeb中Servlet的生命周期及線程安全問題詳解,Servlet?生命周期可被定義為從創(chuàng)建直到毀滅的整個過程,Servlet體系結(jié)構(gòu)是建立在Java多線程機制之上的,它的生命周期是由Web容器負責的,需要的朋友可以參考下
    2024-01-01
  • mybatis/mybatis-plus模糊查詢語句特殊字符轉(zhuǎn)義攔截器的實現(xiàn)

    mybatis/mybatis-plus模糊查詢語句特殊字符轉(zhuǎn)義攔截器的實現(xiàn)

    在開發(fā)中,我們通常會遇到這樣的情況。用戶在錄入信息是錄入了‘%’,而在查詢時無法精確匹配‘%’。究其原因,‘%’是MySQL的關(guān)鍵字,如果我們想要精確匹配‘%’,那么需要對其進行轉(zhuǎn)義,本文就詳細的介紹一下
    2021-11-11
  • 基于springboot處理date參數(shù)過程解析

    基于springboot處理date參數(shù)過程解析

    這篇文章主要介紹了基于springboot處理date參數(shù)過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-12-12
  • Spring Boot中使用Spring-Retry重試框架的實現(xiàn)

    Spring Boot中使用Spring-Retry重試框架的實現(xiàn)

    本文主要介紹了Spring Boot中使用Spring-Retry重試框架的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-04-04
  • 淺析Java中Future接口的使用方法

    淺析Java中Future接口的使用方法

    在Java開發(fā)中,異步編程是提高系統(tǒng)性能和響應能力的重要手段之一。本文將深入探討Future接口的原理和源碼解讀,幫助讀者更好地理解Future接口的工作機制和使用方法
    2023-05-05
  • SpringBoot?項目的創(chuàng)建與啟動步驟詳解

    SpringBoot?項目的創(chuàng)建與啟動步驟詳解

    這篇文章主要介紹了SpringBoot?項目的創(chuàng)建與啟動,本文分步驟給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-03-03
  • 使用Java第三方實現(xiàn)發(fā)送短信功能

    使用Java第三方實現(xiàn)發(fā)送短信功能

    這篇文章主要介紹了使用Java第三方實現(xiàn)發(fā)送短信功能,在一些開發(fā)中,經(jīng)常需要有給用戶發(fā)送短信接收驗證碼的功能,那么在Java中該如何實現(xiàn)呢,今天我們就一起來看一看
    2023-03-03
  • java基于servlet實現(xiàn)文件上傳功能解析

    java基于servlet實現(xiàn)文件上傳功能解析

    這篇文章主要為大家詳細介紹了java基于servlet實現(xiàn)上傳功能,后臺使用java實現(xiàn),前端主要是js的ajax實現(xiàn),感興趣的小伙伴們可以參考一下
    2016-05-05

最新評論