2011-09-19 73 views
1

這個問題使我瘋狂。我有以下代碼:使用JSP發送電子郵件

<html> 
<body> 
<%@ page import="java.util.*" %> 
<%@ page import="javax.mail.*" %> 
<%@ page import="javax.mail.internet.*" %> 
<%@ page import="javax.activation.*" %> 
<% 
String host = "exchsrv2"; 
String to = "[email protected]"; 
String from = "[email protected]"; 
String subject = "test"; 
String messageText = "body test"; 

Properties props = System.getProperties(); 
props.put("mail.host", host); 
props.put("mail.transport.protocol", "smtp"); 
props.put("mail.smtp.port", "25"); 
Session mailSession = Session.getDefaultInstance(props, null); 

Message msg = new MimeMessage(mailSession); 
msg.setFrom(new InternetAddress(from)); 
InternetAddress[] address = {new InternetAddress(to)}; 
msg.setRecipients(Message.RecipientType.TO, address); 
msg.setSubject(subject); 
msg.setSentDate(new Date()); 
msg.setText(messageText); 

Transport.send(msg); 
out.println("Mail was sent to " + to); 
out.println(" from " + from); 
out.println(" using host " + host + "."); 
%> 
</body> 
</html> 

好了,問題是,我得到以下錯誤:

javax.servlet.ServletException: javax.mail.MessagingException: Could not connect to SMTP host: exchsrv2, port: 25; 
nested exception is: 
java.net.SocketException: Permission denied: connect 
org.apache.jasper.runtime.PageContextImpl.doHandlePageException(PageContextImpl.java:911) 
org.apache.jasper.runtime.PageContextImpl.handlePageException(PageContextImpl.java:840) 
org.apache.jsp.alan_jsp._jspService(alan_jsp.java:113) 
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70) 
javax.servlet.http.HttpServlet.service(HttpServlet.java:722) 
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:433) 
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:389) 
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:333) 
javax.servlet.http.HttpServlet.service(HttpServlet.java:722) 

我知道Exchange服務器是存在的。我可以telnet到它就好了。我的Exchange服務器設置爲不需要驗證。我有一個在C#/。NET中正常工作的程序,並且它工作正常,所以我知道問題不在Exchange服務器中。我在這裏做錯了什麼?

+0

如果您認爲這不是Exchange服務器問題,也許嘗試使用例如gmail帳戶發送郵件 - http://www.mkyong.com/java/javamail-api-sending-email-via- gmail-smtp-example/ – mmatloka

+0

'Permission denied' _usually_意味着您嘗試連接的端口被防火牆擋住。 –

回答

7

好的,我會說在嘗試連接時存在身份驗證問題。您不提供任何用戶名或密碼,除非您的交換服務器不需要用戶名和密碼。


UPDATE:如果使用JDK 7請參見下面的文章,它解決了這個問題:

Defect - JDK7 Permission Denied with Sockets when using VPN

「更多挖四周,似乎在VPN客戶端有IPv6的禁用,這是造成與問題JDK7。如果我使用下面的標誌-Djava.net.preferIPv4Stack = true我不再看到錯誤,這是預期的解決方法還是這是一個問題?「


public class MailTest { 

    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String[] args) throws MessagingException { 
     String host = "smtp.gmail.com"; 
     String to = "[email protected]"; 
     String from = "[email protected]"; 
     String subject = "test"; 
     String messageText = "body test"; 

     Properties props = System.getProperties(); 
     props.put("mail.host", host); 
     props.put("mail.transport.protocol", "smtp"); 
     props.put("mail.smtp.port", "25"); 

     // If using authentication, otherwise comment out 
     props.put("mail.smtp.auth", "true"); 

     // Gmail requires TLS, your server may not 
     props.put("mail.smtp.starttls.enable", "true"); 

     Session mailSession = Session.getDefaultInstance(props, null); 

     Message msg = new MimeMessage(mailSession); 
     msg.setFrom(new InternetAddress(from)); 
     InternetAddress[] address = {new InternetAddress(to)}; 
     msg.setRecipients(Message.RecipientType.TO, address); 
     msg.setSubject(subject); 
     msg.setSentDate(new Date()); 
     msg.setText(messageText); 

     Transport transport = mailSession.getTransport("smtp"); 

     //connect with authentication 
     //transport.connect(host,"myUsername" , "myPassword"); 

     //connect without authentication 
     transport.connect(); 
     transport.sendMessage(msg, address); 

     transport.close(); 

     System.out.println("Mail was sent to " + to); 
     System.out.println(" from " + from); 
     System.out.println(" using host " + host + "."); 

    } 
} 
+0

它解析爲10.0.0.7及其正確解析。交換服務器不需要用戶名或密碼。如果我將「exchsrv2」更改爲「10.0.0.7」,則會出現同樣的問題。 – Icemanind

+0

這裏是另一個人有交換和javamail的問題:http://stackoverflow.com/questions/1713116/javamail-exchange-authentication和另一個:http://stackoverflow.com/questions/3685182/java-mail-client -to-ms-exchange-server - 你的c#程序是否通過端口25上的smtp連接?我已經看到參考Excahnge默認情況下不運行SMTP。 –

+0

我也建議把這個全部放在java類中而不是scriptlet中,然後你可以使用JUnit來測試,JSP scriptlet中的編碼和調試是次優的。 –

1

如果你不想更改首選IP堆棧IPv4的替代解決方案可能是使用的IPv6地址的DHCP名代替主機,例如:

String host = "fe80::b84d:1ed2:5329:de87%10"; 

錯誤的原因確實是從Windows JDK 7開始在Windows上默認使用IPv6。當您嘗試連接到IPv4地址,然後在封面下使用IPv4映射的IPv6地址(請參閱this blog from the Oracle website)。但通常情況下,如果您的交換服務器支持IPv6,這應該不成問題。但是,在切換到JDK 7後,我通過MS Exchange 2010服務器從Java代碼發送郵件時出現類似問題。奇怪的是,根據this link on MS Technet,它支持IPv6。由於我不想將我們的完整應用程序的IP堆棧默認爲IPv4,因此在啓動應用程序時通過設置標誌-Djava.net.preferIPv4Stack = true來接受的解決方案不是一種選擇。因此,將主機名更改爲有效的IPv6對我來說是更好的解決方案。它不是100%清楚爲什麼這可以工作,而不是DHCP名稱。

-1
 <% 
     String host = "smtp.gmail.com"; 
     String from="[email protected]";//Your E-mail-Id 
     String pass="xxxxxx";  //your e-mail account password 

String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory"; 
String to = "[email protected]"; //recipient E-mail-Id 
String from = "[email protected]"; // Your E-mail Id 
String subject ="test mail"; 
String messageText = "hello abc"; 
boolean sessionDebug = true; 


Properties props = System.getProperties(); 
props.put("mail.host", host); 
props.put("mail.transport.protocol.", "smtp"); 
props.put("mail.smtp.auth", "true"); 
props.put("mail.smtp.", "true"); 
props.put("mail.smtp.port", "465");//port number 465 for Secure (SSL) and we can also   use port no 587 for Secure (TLS) 
props.put("mail.smtp.socketFactory.fallback", "false"); 
props.put("mail.smtp.socketFactory.class", SSL_FACTORY); 


Session mailSession = Session.getDefaultInstance(props, null); 
mailSession.setDebug(sessionDebug); 


Message msg = new MimeMessage(mailSession); 
msg.setFrom(new InternetAddress(from)); 
InternetAddress[] address = {new InternetAddress(to)}; 
msg.setRecipients(Message.RecipientType.TO, address); 
msg.setSubject(subject); 
msg.setContent(messageText, "text/html"); 


Transport transport = mailSession.getTransport("smtp"); 
transport.connect(host, user, pass); 


try { 
     transport.sendMessage(msg, msg.getAllRecipients()); 
     out.println("Send Success"); 
     boolean WasEmailSent = true; // assume it was sent 
    } 

catch (Exception err) { 
         boolean WasEmailSent = false; 
         } 
        transport.close(); 
     %> 
+1

解釋你的代碼。只有代碼答案不值得讚賞。 –