使用 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 服务器在那里。我可以很好地远程登录到它。我的 Exchange 服务器设置为不需要身份验证。我有一个在 C#/.NET 中运行良好的程序,而且它运行良好,所以我知道问题不在 Exchange 服务器中。我在这里做错了什么?
This problem is driving me nuts. I have the following code:
<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>
Okay, the problem is, I get the following error:
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)
I know Exchange server is there. I can telnet to it just fine. My Exchange server is setup to not require authentication. I got a program that works fine in C#/.NET, and it works fine, so I know the problem isn't in the Exchange server. What am I doing wrong here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我会立即说尝试连接时存在身份验证问题。您无需提供任何用户名或密码,除非您的交换服务器不需要用户名和密码。
更新:如果使用 JDK 7,请参阅以下帖子,它解决了此问题:
缺陷 - 使用 VPN 时套接字拒绝 JDK7 权限
“进一步挖掘,VPN 客户端似乎禁用了 IPv6,这导致 JDK7 出现问题。如果我使用以下标志 -Djava.net.preferIPv4Stack=true,我将不再看到错误。这是预期的解决方法还是这是一个问题吗?”
Well offhand I would say there is an authentication issue when trying to connect. You are not providing any username or password, unless your exchange server doesn't require username and password.
UPDATE: If using JDK 7 see the following post, it resolved this issue:
Defect - JDK7 Permission Denied with Sockets when using VPN
"More digging around and it seems the VPN client has IPv6 disabled which is causing issues with JDK7. If I use the following flag -Djava.net.preferIPv4Stack=true I no longer see the errors. Is this workaround expected or is this an issue?"
如果您不想将首选 IP 堆栈更改为 IPv4,另一种解决方案可能是使用主机的 IPv6 地址而不是 DHCP 名称,例如:
错误的原因确实是 Windows 启动时默认使用 IPv6从 JDK 7 开始。当您尝试连接到 IPv4 地址时,它会在幕后使用 IPv4 映射的 IPv6 地址(请参阅 此博客来自 Oracle 网站)。但通常情况下,如果您的交换服务器支持 IPv6,这应该没有问题。但是,在切换到 JDK 7 后,我在通过 MS Exchange 2010 Server 从 Java 代码发送邮件时遇到了类似的问题。奇怪的是,根据 MS Technet 上的此链接 它支持 IPv6。由于我不想将整个应用程序的 IP 堆栈默认为 IPv4,因此在启动应用程序时通过设置标志 -Djava.net.preferIPv4Stack=true 来接受的解决方案不是一个选项。因此,对于我来说,将主机名更改为有效的 IPv6 是更好的解决方案。我并不是 100% 清楚为什么这个有效,而不是 DHCP 名称。
If you do not want to change the preferred IP stack to IPv4, an alternative solution might be to use the IPv6 address for the host in stead of the DHCP name, e.g.:
The reason of the error is indeed that IPv6 is defaulted on Windows starting from JDK 7. When you attempt to connect to an IPv4 address then under the covers it will use an IPv4-mapped IPv6 address (see this blog from the Oracle website). But normally this should be no problem, if your exchange server supports IPv6. However, I ran in a similar issue when sending a mail from Java code through an MS Exchange 2010 Server after switching to JDK 7. The strange thing is that according to this link on MS Technet it supports IPv6. Since I did not want to default the IP stack of our complete application to IPv4, the accepted solution by setting the flag -Djava.net.preferIPv4Stack=true when starting the application was not an option. Thus changing the host name to a valid IPv6 was a better solution in my case. It's not 100% clear to me why this works and not the DHCP name.