Deskripsi adegan:
Saat menyimpan konfigurasi kotak surat, secara otomatis mendeteksi apakah parameter konfigurasi kotak surat sudah benar. Ditemukan bahwa ketika mendeteksi SMTP, sistem melaporkan pengecualian berikut:
Copy kode kodenya sebagai berikut:
javax.mail.MessagingException: 501 Perintah "HELO" memerlukan argumen
di com.sun.mail.smtp.SMTPTransport.issueCommand(SMTPTransport.java:1363)
di com.sun.mail.smtp.SMTPTransport.helo(SMTPTransport.java:838)
di com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:375)
di javax.mail.Service.connect(Service.java:275)
Namun, ketika saya beralih ke server Windows, saya menemukan bahwa tidak ada masalah seperti itu. Ini hanya dapat direproduksi di server Linux. Tampaknya secara intuitif ada yang salah dengan beberapa konfigurasi server Linux ini.
Langkah-langkah pemecahan masalah
1. Temukan server Linux dengan sistem operasi yang sama, verifikasi konfigurasi email, OK, dan hilangkan masalah khusus sistem operasi Linux.
2. Gunakan telnet langsung di server Linux untuk menyambung ke port SMTP server email lawan. Oke, atasi masalah jaringan server.
3. Temukan penjelasan instruksi HELO
Copy kode kodenya sebagai berikut:
HALO
-- Memulai percakapan dengan server email. Saat menggunakan perintah ini, Anda dapat menentukan nama domain Anda sehingga server email mengetahui siapa Anda.
Ditemukan bahwa perintah HELO perlu diikuti dengan nama host pemrakarsa untuk memberi tahu server SMTP di mana sumber pesan berada.
Melihat pesan pengecualian "Perintah 501 "HELO" memerlukan argumen", jelas bahwa program tidak meneruskan nama domain host sumber selama interaksi dengan SERVER SMTP.
4. Lihat kode sumber JAVA MAIL
Temukan instruksi HELO, sebagai berikut:
Copy kode kodenya sebagai berikut:
/**
* Keluarkan perintah <code>HELO</code>.
*
* @domain param
* domain kami
*
* @sejak JavaMail 1.4.1
*/
void helo yang dilindungi (domain string) memunculkan MessagingException {
jika (domain != nol)
issueCommand("HELO " + domain, 250);
kalau tidak
issueCommand("HELO", 250);
}
Temukan di mana metode helo dipanggil dan lihat bagaimana domain diteruskan
Copy kode kodenya sebagai berikut:
jika (gunakanEhlo)
berhasil = ehlo(getLocalHost());
jika (!berhasil)
halo(getLocalHost());
Tentu saja, cari metode getLocalHost(), yang didefinisikan sebagai berikut:
Copy kode kodenya sebagai berikut:
/**
* Dapatkan nama host lokal, untuk digunakan dalam perintah EHLO dan HELO.
* Properti mail.smtp.localhost menggantikan mail.smtp.localaddress, yang mana
* mengesampingkan apa yang InetAddress katakan kepada kita.
*/
String tersinkronisasi publik getLocalHost() {
mencoba {
// ambil nama host kami dan simpan dalam cache untuk digunakan di masa mendatang
jika (localHostName == null || localHostName.length() <= 0)
localHostName = session.getProperty("mail." + nama + ".localhost");
jika (localHostName == null || localHostName.length() <= 0)
localHostName = session.getProperty("mail." + nama+ ".localaddress");
if (localHostName == null || localHostName.length() <= 0) {
InetAddress localHost = InetAddress.getLocalHost();
localHostName = localHost.getHostName();
// jika kami tidak bisa mendapatkan nama kami, gunakan literal alamat lokal
jika (namaHostlokal == nol)
// XXX - tidak benar untuk IPv6
localHostName = "[" + localHost.getHostAddress() + "]";
}
} tangkapan (UnknownHostException uhex) {
}
kembalikan namahost lokal;
}
Anda dapat melihat bahwa nama host dapat diperoleh dari atribut sesi koneksi saat ini, atau dari konfigurasi host server saat ini. Namun, program kami tidak menetapkan nama host dalam sesi tersebut, jadi alasannya pasti terletak pada file host server Linux telah dimodifikasi, menyebabkan program JAVA tidak dapat memperoleh localhostName secara otomatis.
5. Cek file /etc/hosts, keadaannya sebagai berikut:
Copy kode kodenya sebagai berikut:
127.0.0.1 localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6
Cukup modifikasi file host sebagai berikut:
Copy kode kodenya sebagai berikut:
127.0.0.1 host lokal
::1 localhost6.localdomain6 localhost6
6. Tes ulang dan masalahnya terpecahkan.
Faktanya, situasi ini juga dapat dihindari melalui pemrograman, yaitu menambahkan atribut nama host dari server saat ini ke koneksi sesi.
Copy kode kodenya sebagai berikut:
public static void main(String[] args) {
mencoba {
int smtpport = 25;
String smtpserver = "219.147.xxx.xxx";
Properti prop = System.getProperties();
prop.put("mail.smtp.auth", "benar");
prop.put("mail.smtp.localhost", "myMailServer");
Sesi mailSession = Session.getInstance(prop, null);
Transportasi transport = mailSession.getTransport("smtp");
transport.connect(smtpserver,smtpport, "nama pengguna", "kata sandi");
System.out.println("koneksi oke");
transport.close();
} catch (AuthenticationFailedException id) {
en.printStackTrace();
System.out.println("Koneksi server SMTP gagal, harap periksa apakah informasi yang dimasukkan sudah benar");
} tangkapan (NoSuchProviderException e) {
e.printStackTrace();
System.out.println("Koneksi server SMTP gagal, harap periksa apakah informasi yang dimasukkan sudah benar");
} tangkapan (MessagingException e) {
e.printStackTrace();
System.out.println("Koneksi server SMTP gagal, harap periksa apakah informasi yang dimasukkan sudah benar");
}
}