คำอธิบายฉาก:
เมื่อบันทึกการกำหนดค่ากล่องจดหมาย ระบบจะตรวจพบโดยอัตโนมัติว่าพารามิเตอร์การกำหนดค่ากล่องจดหมายถูกต้องหรือไม่ โดยพบว่าเมื่อตรวจพบ SMTP ระบบจะรายงานข้อยกเว้นต่อไปนี้:
คัดลอกรหัสรหัส ดังต่อไปนี้:
javax.mail.MessagingException: 501 คำสั่ง "HELO" ต้องมีอาร์กิวเมนต์
ที่ com.sun.mail.smtp.SMTPTransport.issueCommand (SMTPTransport.java:1363)
ที่ com.sun.mail.smtp.SMTPTransport.helo (SMTPTransport.java:838)
ที่ com.sun.mail.smtp.SMTPTransport.protocolConnect (SMTPTransport.java:375)
ที่ javax.mail.Service.connect (Service.java:275)
อย่างไรก็ตาม เมื่อฉันเปลี่ยนไปใช้เซิร์ฟเวอร์ Windows ฉันพบว่าไม่มีปัญหาดังกล่าวสามารถทำซ้ำได้บนเซิร์ฟเวอร์ Linux เท่านั้น ดูเหมือนว่ามีบางอย่างผิดปกติกับการกำหนดค่าบางอย่างของเซิร์ฟเวอร์ Linux นี้
ขั้นตอนการแก้ไขปัญหา
1. ค้นหาเซิร์ฟเวอร์ Linux ที่มีระบบปฏิบัติการเดียวกัน ตรวจสอบการกำหนดค่าอีเมล ตกลง และกำจัดปัญหาเกี่ยวกับลักษณะเฉพาะของระบบปฏิบัติการ Linux
2. ใช้ telnet โดยตรงบนเซิร์ฟเวอร์ Linux เพื่อเชื่อมต่อกับพอร์ต SMTP ของเซิร์ฟเวอร์เมลฝั่งตรงข้าม ตกลง แก้ไขปัญหาเครือข่ายของเซิร์ฟเวอร์
3. ค้นหาคำอธิบายคำสั่ง HELO
คัดลอกรหัสรหัส ดังต่อไปนี้:
สวัสดี
-- เริ่มต้นการสนทนากับเมลเซิร์ฟเวอร์ เมื่อใช้คำสั่งนี้ คุณสามารถระบุชื่อโดเมนของคุณเพื่อให้เมลเซิร์ฟเวอร์รู้ว่าคุณเป็นใคร
พบว่าคำสั่ง HELO จำเป็นต้องตามด้วยชื่อโฮสต์ของตัวเริ่มต้นเพื่อบอกเซิร์ฟเวอร์ SMTP ว่าแหล่งที่มาของข้อความอยู่ที่ใด
เมื่อดูข้อความยกเว้น "คำสั่ง 501 "HELO" ต้องมีอาร์กิวเมนต์" เห็นได้ชัดว่าโปรแกรมไม่ส่งชื่อโดเมนโฮสต์ต้นทางระหว่างการโต้ตอบกับเซิร์ฟเวอร์ SMTP
4. ดูซอร์สโค้ด JAVA MAIL
ค้นหาคำสั่ง HELO ดังนี้:
คัดลอกรหัสรหัส ดังต่อไปนี้:
-
* ออกคำสั่ง <code>HELO</code>
-
* โดเมน @param
* โดเมนของเรา
-
* @ตั้งแต่ JavaMail 1.4.1
-
การป้องกันเป็นโมฆะ helo (โดเมนสตริง) พ่น MessagingException {
ถ้า (โดเมน != null)
issueCommand("HELO" + โดเมน, 250);
อื่น
issueCommand("HELO", 250);
-
ค้นหาตำแหน่งที่เรียกเมธอด helo และดูว่าโดเมนถูกส่งผ่านอย่างไร
คัดลอกรหัสรหัส ดังต่อไปนี้:
ถ้า (ใช้Ehlo)
สำเร็จ = ehlo(getLocalHost());
ถ้า (!สำเร็จ)
เฮโล(getLocalHost());
โดยปกติแล้ว ให้มองหาเมธอด getLocalHost() ซึ่งกำหนดไว้ดังนี้:
คัดลอกรหัสรหัส ดังต่อไปนี้:
-
* รับชื่อของโลคัลโฮสต์ เพื่อใช้ในคำสั่ง EHLO และ HELO
* คุณสมบัติ mail.smtp.localhost จะแทนที่ mail.smtp.localaddress ซึ่ง
* แทนที่สิ่งที่ InetAddress จะบอกเรา
-
สตริงซิงโครไนซ์สาธารณะ getLocalHost() {
พยายาม {
// รับชื่อโฮสต์ของเราและแคชเพื่อใช้ในอนาคต
ถ้า (localHostName == null || localHostName.length() <= 0)
localHostName = session.getProperty("mail." + ชื่อ + ".localhost");
ถ้า (localHostName == null || localHostName.length() <= 0)
localHostName = session.getProperty("mail." + name+ ".localaddress");
ถ้า (localHostName == null || localHostName.length() <= 0) {
InetAddress localHost = InetAddress.getLocalHost();
localHostName = localHost.getHostName();
// หากเราไม่สามารถรับชื่อของเราได้ ให้ใช้ค่าตามตัวอักษรของท้องถิ่น
ถ้า (localHostName == null)
// XXX - ไม่ถูกต้องสำหรับ IPv6
localHostName = "[" + localHost.getHostAddress() + "]";
-
} จับ (UnknownHostException uhex) {
-
ส่งคืน localHostName;
-
คุณจะเห็นว่าสามารถรับชื่อโฮสต์ได้จากแอตทริบิวต์เซสชันของการเชื่อมต่อปัจจุบัน หรือจากการกำหนดค่าโฮสต์ของเซิร์ฟเวอร์ปัจจุบัน อย่างไรก็ตาม โปรแกรมของเราไม่ได้ตั้งชื่อโฮสต์ในเซสชัน ดังนั้นเหตุผลจึงต้องอยู่ในไฟล์โฮสต์ ของเซิร์ฟเวอร์ Linux ได้รับการแก้ไข ทำให้โปรแกรม JAVA ไม่สามารถรับ localhostName ได้โดยอัตโนมัติ
5. ตรวจสอบไฟล์ /etc/hosts สถานการณ์จะเป็นดังนี้:
คัดลอกรหัสรหัส ดังต่อไปนี้:
127.0.0.1 localhost.localdomain ท้องถิ่นโฮสต์
::1 localhost6.localdomain6 localhost6
เพียงแก้ไขไฟล์โฮสต์ดังต่อไปนี้:
คัดลอกรหัสรหัส ดังต่อไปนี้:
127.0.0.1 โลคัลโฮสต์
::1 localhost6.localdomain6 localhost6
6. ทดสอบซ้ำและปัญหาได้รับการแก้ไขแล้ว
ในความเป็นจริง สถานการณ์นี้สามารถหลีกเลี่ยงได้ด้วยการเขียนโปรแกรม นั่นคือการเพิ่มแอตทริบิวต์ชื่อโฮสต์ของเซิร์ฟเวอร์ปัจจุบันให้กับการเชื่อมต่อเซสชัน ตัวอย่างโปรแกรม:
คัดลอกรหัสรหัส ดังต่อไปนี้:
โมฆะคงที่สาธารณะ main (String [] args) {
พยายาม {
int smtpport = 25;
สตริง smtpserver = "219.147.xxx.xxx";
เสาคุณสมบัติ = System.getProperties();
prop.put("mail.smtp.auth", "true");
prop.put("mail.smtp.localhost", "myMailServer");
เซสชันเมลเซสชัน = Session.getInstance (prop, null);
การขนส่งการขนส่ง = mailSession.getTransport("smtp");
Transport.connect(smtpserver,smtpport, "ชื่อผู้ใช้", "รหัสผ่าน");
System.out.println("เชื่อมต่อตกลง");
ขนส่ง.ปิด();
} จับ (AuthenticationFailedException en) {
en.printStackTrace();
System.out.println("การเชื่อมต่อเซิร์ฟเวอร์ SMTP ล้มเหลว โปรดตรวจสอบว่าข้อมูลที่ป้อนถูกต้องหรือไม่");
} จับ (NoSuchProviderException จ) {
e.printStackTrace();
System.out.println("การเชื่อมต่อเซิร์ฟเวอร์ SMTP ล้มเหลว โปรดตรวจสอบว่าข้อมูลที่ป้อนถูกต้องหรือไม่");
} จับ (MessagingException จ) {
e.printStackTrace();
System.out.println("การเชื่อมต่อเซิร์ฟเวอร์ SMTP ล้มเหลว โปรดตรวจสอบว่าข้อมูลที่ป้อนถูกต้องหรือไม่");
-
-