วันนี้เพื่อนร่วมงานประสบปัญหา เมื่อใช้ JAVA MAIL เพื่อรับอีเมล หากผู้รับเป็นรายชื่อและรายชื่อผู้รับถูกคั่นด้วยเครื่องหมายอัฒภาค จะมีข้อยกเว้นเกิดขึ้นใน JAVA MAIL และไม่สามารถแยกวิเคราะห์ได้ตามปกติ ดูสิ ฉันเขียนการสาธิตง่ายๆ ง่ายมาก เช่น:
คัดลอกรหัสรหัส ดังต่อไปนี้:
@ทดสอบ
โมฆะสาธารณะ testReceiveMail() {
พยายาม {
โฮสต์สตริง = "pop3.163.com";
คุณสมบัติปรากฏขึ้น = คุณสมบัติใหม่ ();
pops.put("mail.pop3.host", โฮสต์);
pops.put("mail.pop.auth", "true");
เซสชั่นเซสชั่น = Session.getDefaultInstance (ป๊อป, null);
ร้านค้า ร้านค้า = session.getStore("pop3");
//เชื่อมต่อกับเมลเซิร์ฟเวอร์
store.connect(โฮสต์, "chb_go", "3870359346");
//รับอินบ็อกซ์.
โฟลเดอร์กล่องจดหมาย = store.getDefaultFolder().getFolder("INBOX");
//อ่านอย่างเดียวก็พอ
inbox.open(โฟลเดอร์.READ_ONLY);
//รับรายชื่อผู้รับจดหมายทั้งหมด
ข้อความ [] msg = inbox.getMessages();
โปรไฟล์ FetchProfile = FetchProfile ใหม่ ();
profile.add(FetchProfile.Item.ENVELOPE);
inbox.fetch(ข้อความ, โปรไฟล์);
สำหรับ (int i = 0; i < msg.length; i++) {
System.out.println("=========================================== = ====");
System.out.println("หัวเรื่อง: "+msg[i].getSubject());
InternetAddress[] toAddress = (InternetAddress[]) msg[i].getRecipients(Message.RecipientType.TO);
สำหรับ(ที่อยู่อินเทอร์เน็ตที่อยู่:ถึงที่อยู่){
System.out.println(ที่อยู่.getAddress());
-
-
//ปิดทรัพยากรที่เปิดอยู่
ถ้า (inbox != null)
inbox.ปิด(จริง);
ถ้า (เก็บ != null)
ร้านค้า.ปิด();
} จับ (NoSuchProviderException จ) {
e.printStackTrace();
} จับ (MessagingException จ) {
e.printStackTrace();
} จับ (ข้อยกเว้นจ) {
e.printStackTrace();
-
-
ง่ายมาก คุณสามารถรับอีเมลได้ตามปกติและแสดงรายชื่อผู้รับได้ตามปกติ แต่เมื่อเชื่อมต่อกับเมลเซิร์ฟเวอร์ภายในและผู้รับเป็นอีเมลที่มีเครื่องหมายอัฒภาคเป็นตัวคั่น ผู้รับจะไม่สามารถแสดงได้ตามปกติ
หลังจากค้นหาข้อกำหนดแล้ว ฉันพบว่า FRC 822 กำหนดให้ผู้รับต้องคั่นด้วยเครื่องหมายจุลภาค ดูเหมือนว่าการแยกเครื่องหมายอัฒภาคไม่ใช่ตัวคั่นมาตรฐาน ดังต่อไปนี้:
คัดลอกรหัสรหัส ดังต่อไปนี้:
Destination = "ถึง" ซิลิโคน 1#address ; Primary
/ "Resent-To" Lagu: 1#address
/ "cc" ซิลิโคน 1#address ;
/ "Resent-cc" Lagu: 1#address
/ "bcc" ซิลิโคน #address ; blind carbon
/ "Resent-bcc" ซิลิโคน #address
ไวยากรณ์ # แสดงถึงรายการ และเนื้อหาระหว่างรายการจะถูกคั่นด้วยเครื่องหมายจุลภาค ตัวอย่างเช่น:
คัดลอกรหัสรหัส ดังต่อไปนี้:
2.7. #กฎ: รายการ
โครงสร้าง "#" ถูกกำหนดไว้ คล้ายกับ "*" ดังนี้:
<l>#<m>องค์ประกอบ
ระบุอย่างน้อย <l> และมากที่สุด <m> องค์ประกอบ โดยแต่ละองค์ประกอบคั่นด้วยเครื่องหมายจุลภาค (",") ซึ่งทำให้รูปแบบรายการปกติง่ายมาก เช่น '(องค์ประกอบ *("," องค์ประกอบ) ))' สามารถแสดงเป็น "1#element" ได้ทุกที่ที่มีการใช้โครงสร้างนี้ อนุญาตให้ใช้องค์ประกอบที่เป็นโมฆะได้ แต่จะไม่สนับสนุนการนับองค์ประกอบที่มีอยู่ นั่นคือ "(องค์ประกอบ),,(องค์ประกอบ)" จะได้รับอนุญาต แต่นับเป็นเพียงสององค์ประกอบ ดังนั้น ในกรณีที่ต้องมีองค์ประกอบอย่างน้อยหนึ่งรายการ จะต้องมีองค์ประกอบที่ไม่เป็นโมฆะอย่างน้อยหนึ่งรายการ ค่าเริ่มต้นคือ 0 และอนันต์เพื่อให้ "#(องค์ประกอบ)" อนุญาตตัวเลขใดๆ รวมทั้ง ศูนย์; "1#element" ต้องมีอย่างน้อยหนึ่งรายการ และ "1#2element" อนุญาตหนึ่งหรือสองรายการ
JAVA MAIL ทำงานอย่างเคร่งครัดตามข้อกำหนด RFC 822 และไม่เกี่ยวข้องกับอัฒภาค เมลเซิร์ฟเวอร์ส่วนใหญ่ปฏิบัติตามข้อกำหนด RFC 822 อย่างเคร่งครัด เช่น Lotus Notes และ gmail (ผู้รับ gmail ไม่สามารถป้อนเครื่องหมายอัฒภาคได้ และมันจะถูกแทนที่ด้วยเครื่องหมายจุลภาคโดยอัตโนมัติเช่นกัน อย่างไรก็ตาม คุณจะพบว่าเมื่อส่ง) อีเมลมักถูกคั่นด้วยเครื่องหมายอัฒภาค เนื่องจากเครื่องมืออีเมลบางอย่างของ Microsoft เช่น Outlook, Outlook Express หรือ MAPI ใช้เครื่องหมายอัฒภาคเป็นตัวคั่น นอกจากนี้ ฉันคิดว่ามีการใช้เครื่องหมายอัฒภาคอย่างกว้างขวาง ฉันดูถูก Microsoft อย่างยิ่ง! มีความผิดปกติมากเกินไป! -
หากคุณโชคไม่ดีและพบผู้ใช้ที่คุ้นเคยกับการใช้อัฒภาคเป็นตัวคั่น และเมลเซิร์ฟเวอร์ของพวกเขาไม่ได้แทนที่อัฒภาคด้วยเครื่องหมายจุลภาคโดยอัตโนมัติ จากนั้นเราจะทำความเข้ากันได้ผ่านโปรแกรมเท่านั้น คุณสามารถพิจารณาแก้ไขซอร์สโค้ด JAVA MAIL ได้
ซอร์สโค้ดของวิธีแยกวิเคราะห์ของคลาส InternetAddress จะไม่แสดงที่นี่ คุณเพียงแค่ต้องแก้ไขการประมวลผลของอัฒภาคให้เหมือนกับเครื่องหมายจุลภาค (แต่อัฒภาคยังถูกกำหนดไว้ใน FRC 822 การแก้ไขดังกล่าวอาจทำให้เกิดอันตรายที่ซ่อนอยู่ ดังนั้น โปรดใช้ความระมัดระวัง)