前言java
首先,須要說明的是,本錯誤來自於一個簡單的基於java mail的api程序,郵件服務器是163的SMTP,即smtp.163.com.api
程序服務器
須要說明一下,下面這個程序,是來自於網絡上,本人爲了測試本身項目MUEAS中重置密碼,經過郵件認證明現重置功能,臨時用來測試用的,如有異議,請給我留言。我將會本身寫一份。網絡
1 package com.shihuc.demo; 2 3 import java.util.*; 4 import java.io.*; 5 import javax.mail.*; 6 import javax.mail.internet.*; 7 import javax.activation.*; 8 9 public class SendEmail 10 { 11 //收件人郵箱地址 12 private String to; 13 //發件人郵箱地址 14 private String from; 15 //SMTP服務器地址 16 private String smtpServer; 17 //登陸SMTP服務器的用戶名 18 private String username ; 19 //登陸SMTP服務器的密碼 20 private String password ; 21 //郵件主題 22 private String subject; 23 //郵件正文 24 private String content; 25 //記錄全部附件文件的集合 26 List<String> attachments = new ArrayList<String>(); 27 //無參數的構造器 28 public SendEmail() 29 { 30 } 31 32 public SendEmail(String to , String from , String smtpServer 33 , String username , String password 34 , String subject , String content) 35 { 36 this.to = to; 37 this.from = from; 38 this.smtpServer = smtpServer; 39 this.username = username; 40 this.password = password; 41 this.subject = subject; 42 this.content = content; 43 } 44 //to屬性的setter方法 45 public void setTo(String to) 46 { 47 this.to = to; 48 } 49 //from屬性的setter方法 50 public void setFrom(String from) 51 { 52 this.from = from; 53 } 54 //smtpServer屬性的setter方法 55 public void setSmtpServer(String smtpServer) 56 { 57 this.smtpServer = smtpServer; 58 } 59 //username屬性的setter方法 60 public void setUsername(String username) 61 { 62 this.username = username; 63 } 64 //password屬性的setter方法 65 public void setPassword(String password) 66 { 67 this.password = password; 68 } 69 //subject屬性的setter方法 70 public void setSubject(String subject) 71 { 72 this.subject = subject; 73 } 74 //content屬性的setter方法 75 public void setContent(String content) 76 { 77 this.content = content; 78 } 79 //把郵件主題轉換爲中文 80 public String transferChinese(String strText) 81 { 82 try 83 { 84 strText = MimeUtility.encodeText(new String(strText.getBytes() , "GB2312"), "GB2312", "B"); 85 } 86 catch(Exception e) 87 { 88 e.printStackTrace(); 89 } 90 return strText; 91 } 92 //增長附件,將附件文件名添加的List集合中 93 public void attachfile(String fname) 94 { 95 attachments.add(fname); 96 } 97 //發送郵件 98 public boolean send() 99 { 100 //建立郵件Session所需的Properties對象 101 Properties props = new Properties(); 102 props.put("mail.smtp.host" , smtpServer); 103 props.put("mail.smtp.auth" , "true"); 104 props.put("mail.smtp.debug" , "true"); 105 //建立Session對象 106 Session session = Session.getDefaultInstance(props 107 //以匿名內部類的形式建立登陸服務器的認證對象 108 , new Authenticator() 109 { 110 public PasswordAuthentication getPasswordAuthentication() 111 { 112 return new PasswordAuthentication(username, password); 113 } 114 }); 115 try 116 { 117 //構造MimeMessage並設置相關屬性值 118 MimeMessage msg = new MimeMessage(session); 119 //設置發件人 120 msg.setFrom(new InternetAddress(from)); 121 //設置收件人 122 InternetAddress[] addresses = {new InternetAddress(to)}; 123 msg.setRecipients(Message.RecipientType.TO , addresses); 124 //設置郵件主題 125 subject = transferChinese(subject); 126 msg.setSubject(subject); 127 //構造Multipart 128 Multipart mp = new MimeMultipart(); 129 //向Multipart添加正文 130 MimeBodyPart mbpContent = new MimeBodyPart(); 131 mbpContent.setText(content); 132 //將BodyPart添加到MultiPart中 133 mp.addBodyPart(mbpContent); 134 //向Multipart添加附件 135 //遍歷附件列表,將全部文件添加到郵件消息裏 136 for(String efile : attachments) 137 { 138 MimeBodyPart mbpFile = new MimeBodyPart(); 139 //以文件名建立FileDataSource對象 140 FileDataSource fds = new FileDataSource(efile); 141 //處理附件 142 mbpFile.setDataHandler(new DataHandler(fds)); 143 mbpFile.setFileName(fds.getName()); 144 //將BodyPart添加到MultiPart中 145 mp.addBodyPart(mbpFile); 146 } 147 //清空附件列表 148 attachments.clear(); 149 //向Multipart添加MimeMessage 150 msg.setContent(mp); 151 //設置發送日期 152 msg.setSentDate(new Date()); 153 //發送郵件 154 Transport.send(msg); 155 } 156 catch (MessagingException mex) 157 { 158 mex.printStackTrace(); 159 return false; 160 } 161 return true; 162 } 163 public static void main(String[] args) 164 { 165 SendEmail sendMail = new SendEmail(); 166 sendMail.setSmtpServer("smtp.163.com"); 167 //此處設置登陸的用戶名 168 sendMail.setUsername("你本身合法的163郵箱"); 169 //此處設置登陸的密碼,這個密碼很是重要,它不是郵箱帳戶的登陸密碼,而是應用密碼,須要登陸郵箱,在設置中開啓此應用 170 //不然極可能出現以下錯誤: 171 //javax.mail.AuthenticationFailedException: 550 User has no permission 172 sendMail.setPassword("你本身的應用密碼"); 173 //設置收件人的地址 174 sendMail.setTo("你但願將郵件發給的對方的郵件地址"); 175 //設置發送人地址 176 sendMail.setFrom("你本身的合法的163郵箱"); 177 //設置標題 178 sendMail.setSubject("測試郵件標題!"); 179 //設置內容 180 sendMail.setContent("你好這是一個帶多附件的測試郵件!"); 181 //粘貼附件 182 sendMail.attachfile("/opt/attachment.jpg"); 183 if (sendMail.send()) 184 { 185 System.out.println("---郵件發送成功---"); 186 } 187 } 188 }
程序中用到了javax的mail.jar。 maven依賴以下: session
1 <dependency> 2 <groupId>javax.mail</groupId> 3 <artifactId>mail</artifactId> 4 <version>1.4.4</version> 5 </dependency>
注意,上面的郵件發送邏輯是沒有問題的,若發送時,遇到下面的錯誤:eclipse
1 javax.mail.AuthenticationFailedException: 550 User has no permission 2 3 at com.sun.mail.smtp.SMTPTransport$Authenticator.authenticate(SMTPTransport.java:809) 4 at com.sun.mail.smtp.SMTPTransport.authenticate(SMTPTransport.java:752) 5 at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:669) 6 at javax.mail.Service.connect(Service.java:317) 7 at javax.mail.Service.connect(Service.java:176) 8 at javax.mail.Service.connect(Service.java:125) 9 at javax.mail.Transport.send0(Transport.java:194) 10 at javax.mail.Transport.send(Transport.java:124) 11 at com.shihuc.demo.SendEmail.send(SendEmail.java:154) 12 at com.shihuc.demo.SendEmail.main(SendEmail.java:181) 13 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 14 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 15 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 16 at java.lang.reflect.Method.invoke(Method.java:606) 17 at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
則要考慮是否是沒有啓用應用密碼功能。個人測試過程,是經過啓用應用密碼功能,得以將500的問題解決掉的!maven
步驟測試
1. 登陸本身的163郵箱,注意,要用你的應用程序中設置的郵箱地址去登陸。this
2. 在主菜單欄上的「設置」子菜單裏面,選擇POP3/SMTP/IAMP菜單。google
3. 若沒有開啓「客戶端受權密碼」,則選擇將其開啓。開啓後,會給你生成一個應用受權密碼。要用這個生成的密碼做爲java mail API發送郵件的認證密碼,如此,才能解除500密碼,若用郵箱的登陸密碼去設置這個認證密碼,會遇到500的錯誤。下圖是開啓「客戶端受權密碼」功能後的截圖:
這個錯誤,我折騰了很長時間,百度上找了好久,都找不到,google查看的信息,都是基於gmail的問題(535錯誤碼,其實相似163的這個500的錯誤),最後,本身研究了下163郵箱上的功能菜單,摸索着修改,最終解決了這個問題!
有須要的,能夠參考一下,我在這裏,作個memo。