2011-09-19 176 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

解释你的代码。只有代码答案不值得赞赏。 –