可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have tried to write a code to send email using Java. But this code is not working. When the code is executed it gets stuck at transport.send(message). It's stuck there forever. Also I am not sure if the rest of the code is correct or not.
//first from, to, subject, & text values are set
public class SendMail {
private String from;
private String to;
private String subject;
private String text;
public SendMail(String from, String to, String subject, String text){
this.from = from;
this.to = to;
this.subject = subject;
this.text = text;
}
//send method is called in the end
public void send(){
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.port", "465");
Session mailSession = Session.getDefaultInstance(props);
Message simpleMessage = new MimeMessage(mailSession);
InternetAddress fromAddress = null;
InternetAddress toAddress = null;
try {
fromAddress = new InternetAddress(from);
toAddress = new InternetAddress(to);
} catch (AddressException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
simpleMessage.setFrom(fromAddress);
simpleMessage.setRecipient(RecipientType.TO, toAddress);
simpleMessage.setSubject(subject);
simpleMessage.setText(text);
Transport.send(simpleMessage); // this is where code hangs
} catch (MessagingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
回答1:
I ran into exactly the same problem and others have reported intermittent failures. The reason is that Transport.send with SMTP has two infinite timeouts which can result in your process just hanging!
From SUN documentation:
mail.smtp.connectiontimeout int Socket connection timeout value in milliseconds. Default is infinite timeout.
mail.smtp.timeout int Socket I/O timeout value in milliseconds. Default is infinite timeout.
To not "hang" forever, you can set these explicitly:
From SUN: The properties are always set as strings; the Type column describes how the string is interpreted. For example, use
props.put("mail.smtp.port", "888");
Note that if you're using the "smtps" protocol to access SMTP over SSL, all the properties would be named "mail.smtps.*".
So, if you set the two timeouts, you should get a "MessagingException" which you can process with a try/catch rather than having the process just hang.
Assuming that you are using smtp, add the following where t1 and t2 are your timeouts in ms:
props.put("mail.smtp.connectiontimeout", "t1");
props.put("mail.smtp.timeout", "t2");
Of course, this will not fix the root-cause for the timeouts, but it will let you handle the issues gracefully.
Thanks to Siegfried Goeschl's post on Apache Commons
PS: The root cause of problem I experienced seems tied to the network connection I was using while traveling. Apparently the connection was causing an SMTP timeout which I have not had with any other connections.
回答2:
Replace Session.getDefaultInstance with Session.getInstance.
If that doesn't solve the problem, read the JavaMail FAQ, which has debugging tips.
回答3:
I had the exact same issue. I took me multiple hours to find the source of the problem. I was using the wrong dependency / dependency combination...
<dependency>
<groupId>javax.mail</groupId>
<artifactId>javax.mail-api</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.5.3</version>
</dependency>
Changing it to ...
<dependency>
<groupId>javax.mail</groupId>
<artifactId>javax.mail-api</artifactId>
<version>1.5.3</version>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.5.3</version>
</dependency>
... solved the issue.
回答4:
Please try this,
public class SMTPDemo {
public static void main(String args[]) throws IOException,
UnknownHostException {
String msgFile = "file.txt";
String from = "java2s@java2s.com";
String to = "yourEmail@yourServer.com";
String mailHost = "yourHost";
SMTP mail = new SMTP(mailHost);
if (mail != null) {
if (mail.send(new FileReader(msgFile), from, to)) {
System.out.println("Mail sent.");
} else {
System.out.println("Connect to SMTP server failed!");
}
}
System.out.println("Done.");
}
static class SMTP {
private final static int SMTP_PORT = 25;
InetAddress mailHost;
InetAddress localhost;
BufferedReader in;
PrintWriter out;
public SMTP(String host) throws UnknownHostException {
mailHost = InetAddress.getByName(host);
localhost = InetAddress.getLocalHost();
System.out.println("mailhost = " + mailHost);
System.out.println("localhost= " + localhost);
System.out.println("SMTP constructor done\n");
}
public boolean send(FileReader msgFileReader, String from, String to)
throws IOException {
Socket smtpPipe;
InputStream inn;
OutputStream outt;
BufferedReader msg;
msg = new BufferedReader(msgFileReader);
smtpPipe = new Socket(mailHost, SMTP_PORT);
if (smtpPipe == null) {
return false;
}
inn = smtpPipe.getInputStream();
outt = smtpPipe.getOutputStream();
in = new BufferedReader(new InputStreamReader(inn));
out = new PrintWriter(new OutputStreamWriter(outt), true);
if (inn == null || outt == null) {
System.out.println("Failed to open streams to socket.");
return false;
}
String initialID = in.readLine();
System.out.println(initialID);
System.out.println("HELO " + localhost.getHostName());
out.println("HELO " + localhost.getHostName());
String welcome = in.readLine();
System.out.println(welcome);
System.out.println("MAIL From:<" + from + ">");
out.println("MAIL From:<" + from + ">");
String senderOK = in.readLine();
System.out.println(senderOK);
System.out.println("RCPT TO:<" + to + ">");
out.println("RCPT TO:<" + to + ">");
String recipientOK = in.readLine();
System.out.println(recipientOK);
System.out.println("DATA");
out.println("DATA");
String line;
while ((line = msg.readLine()) != null) {
out.println(line);
}
System.out.println(".");
out.println(".");
String acceptedOK = in.readLine();
System.out.println(acceptedOK);
System.out.println("QUIT");
out.println("QUIT");
return true;
}
}
}
回答5:
Had this exact same problem. You have to close the transport in the catch block. The reason the code freezes is because the smtp server connection never gets shut down on the client side unless you do it manually.
try {
simpleMessage.setFrom(fromAddress);
simpleMessage.setRecipient(RecipientType.TO, toAddress);
simpleMessage.setSubject(subject);
simpleMessage.setText(text);
Transport.send(simpleMessage); // this is where code hangs
} catch (MessagingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Transport.close()
}
But the most efficient way to make sure javamail exits correctly is to bundle the javamail logic into one try block and close the transport in a finally block. Try this.
[EDIT] After being alerted that the above code didn't work here is the code that compiles correctly.
import java.util.Properties;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.Message.RecipientType;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
//first from, to, subject, & text values are set
public class SendMail {
private String from;
private String to;
private String subject;
private String text;
public SendMail(String from, String to, String subject, String text) {
this.from = from;
this.to = to;
this.subject = subject;
this.text = text;
}
// send method is called in the end
public void send() throws MessagingException {
Properties props = new Properties();
props.put("mail.transport.protocol", "smtp");
props.put("mail.smtp.host", "localhost");
props.put("mail.smtp.auth", "false");// set to false for no username
props.put("mail.debug", "false");
props.put("mail.smtp.port", "25");
Session session = Session.getDefaultInstance(props);
InternetAddress fromAddress = null;
InternetAddress toAddress = null;
Transport transport = session.getTransport("smtp");
transport.connect();
try {
Message simpleMessage = new MimeMessage(session);
fromAddress = new InternetAddress(from);
toAddress = new InternetAddress(to);
simpleMessage.setFrom(fromAddress);
simpleMessage.setRecipient(RecipientType.TO, toAddress);
simpleMessage.setSubject(subject);
simpleMessage.setText(text);
transport.sendMessage(simpleMessage,
simpleMessage.getAllRecipients());
} catch (MessagingException e) {
e.printStackTrace();
} finally {
transport.close();
}
}
}
回答6:
- Disable all the Antivirus programs.
- Disable the Firewall.
Then give a try, if you succeed, investigate further to find the culprit.
In my case it was the Antivirus, and I had to make an exception for outbound mails on SMTP
to send the mail successfully.
回答7:
When you Declare Transport.send()
it will not work use this instead of
transport.sendMessage(message, message.getAllRecipients());
and also declare a javax.mail.Transport transport = session.getTransport("smtp");
object as shown in the code.
javax.mail.Transport transport = session.getTransport("smtp");
transport.sendMessage(message,message.getAllRecipients());
then the following code will appear like this Thank you, hope this will work perfectly
package org.java.vamsi;
//import javax.activation.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Properties;
//import java.io.*;
//import javax.mail.internet.*;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.mail.Message.RecipientType;
//import com.sun.corba.se.impl.protocol.giopmsgheaders.Message;
//import java.io.*;
//import java.util.*;
//import javax.servlet.*;
//import javax.servlet.http.*;
//import javax.mail.*;
//import javax.mail.internet.*;
//import javax.activation.*;
//import sun.rmi.transport.Transport;
public class SendEmail extends HttpServlet {
private static final long serialVersionUID = 1L;
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
// Recipient's email ID needs to be mentioned.
String to = "mysore.vamsikrishna@gmail.com";
// Sender's email ID needs to be mentioned
String from = "mysore.vamsikrishna007@gmail.com";
// Assuming you are sending email from localhost
String host = "localhost";
// Get system properties
Properties properties = System.getProperties();
// Setup mail server
properties.setProperty("mail.smtp.host", host);
// Get the default Session object.
Session session = Session.getDefaultInstance(properties);
// Set response content type
response.setContentType("text/html");
PrintWriter out = response.getWriter();
try{
javax.mail.Transport transport = session.getTransport("smtp");
// Create a default MimeMessage object.
MimeMessage message = new MimeMessage(session);
// Set From: header field of the header.
message.setFrom(new InternetAddress(from));
// Set To: header field of the header.
message.addRecipient(RecipientType.TO,
new InternetAddress(to));//as we are importing the "javax.mail.Message.RecipientType"
//we have to not set the type as this message.addRecipient(Message.RecipientType.TO,
//new InternetAddress(to));
// Set Subject: header field
message.setSubject("This is the Subject Line!");
// Now set the actual message
message.setText("This is actual message");
// Send message
transport.sendMessage(message,
message.getAllRecipients());
String title = "Send Email";
String res = "Sent message successfully....";
String docType =
"<!doctype html public \"-//w3c//dtd html 4.0 " +
"transitional//en\">\n";
out.println(docType +
"<html>\n" +
"<head><title>" + title + "</title></head>\n" +
"<body bgcolor=\"#f0f0f0\">\n" +
"<h1 align=\"center\">" + title + "</h1>\n" +
"<p align=\"center\">" + res + "</p>\n" +
"</body></html>");
}catch (MessagingException mex) {
mex.printStackTrace();
}
}
}
回答8:
I had AVG Free installed and it was blocking the email being sent.
Open AVG, go to Menu > Settings > Basic Protection > Email Shield
Uncheck "Scan Outbound Emails (SMTP)" and try run your program again.