Sending email using JSP
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 = "alan@domain.com";
String from = "apeince@domain.com";
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.a开发者_StackOverflow社区pache.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?
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?"
public class MailTest {
/**
* @param args the command line arguments
*/
public static void main(String[] args) throws MessagingException {
String host = "smtp.gmail.com";
String to = "myEmail@gmail.com";
String from = "myEmail@gmail.com";
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 + ".");
}
}
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.:
String host = "fe80::b84d:1ed2:5329:de87%10";
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.
<%
String host = "smtp.gmail.com";
String from="send-from@gmail.com";//Your E-mail-Id
String pass="xxxxxx"; //your e-mail account password
String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
String to = "send-to@gmail.com"; //recipient E-mail-Id
String from = "send-from@gmail.com"; // 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();
%>
精彩评论