按理来说用JAVA实现某一邮箱收发件的开发是很简单,有自带的JAVAEmail的jar包实现其功能,起初我也没怎么注意,但最近接了一个某大企业后台管理项目,要实现后台人员接收任务时有邮箱通知,但说的时候并没有提到是内网邮箱,而且提供了一个内网邮箱没有POP3/SMTP服务的开通功能,在测试时始终不知道其邮箱的SMTP地址和端口其邮箱传递的方式等,一直在瞎蒙,原先还以为是SSL加密因为报异常必须SSL加密才能通过,然后从网上找一些常规的默认值,但一直不对,测试两天后,内部人员才找到其内网邮箱服务器配置文档给我才发现是通过TLS1.2加密,并且邮箱端口和SMTP服务器IP还是有些不同的,后面通过其给我的参数我才配置好邮箱
总结一下:在实现邮箱的发送功能必须要知道发送邮箱的SMTP和端口号以及是否加密和加密方式是SSL/TLS才能配置邮箱,一般QQ、新浪等比较常用的邮箱都有着默认的邮箱配置非安全加密时端口为25,加密时为587…这些都能在网上搜到,但一些企业级的邮箱配置甚至只限于局域网时这时候要找到我说的这些信息才能很好的配置一个邮箱发送功能,现在将我写的代码粘贴,代码的参数我是自己写了一个配置文件从配置文件调取以及在Maven里面加了相关的jar包
```import com.manage.common.utils.PropertiesLoader;
import com.manage.common.utils.StringUtils;
import org.apache.commons.mail.Email;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.HtmlEmail;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Date;
import java.util.Properties;
/**
* Email工具类
*
* @author Tonz
* @version 2019-12-01
*/
public class EmailUtils {
//传回操作成功的常量
private static final String SUCCESSCODE = "Success";
//传回操作失败的常量
private static final String FAILCODE = "Failed to send mail";
//传回操作失败的常量
private static final String NOFIND = "Recipient mailbox not found";
//设置实例对象发送邮件的POP3/POP邮件服务器ip、账号、密码
static Message message;
static {
PropertiesLoader property = new PropertiesLoader("intel.properties");
String hostEmailName = property.getProperty("hostEmailName");
String emailSendName = property.getProperty("emailSendName");
String emailSendPwd = property.getProperty("emailSendPwd");
String emailPort = property.getProperty("emailPort");
String SSL = property.getProperty("SSL");
String TLS = property.getProperty("TLS");
String protocol = property.getProperty("emailProtocol");
Properties props = new Properties();
props.setProperty("mail.smtp.host", hostEmailName);
props.setProperty("mail.smtp.port", emailPort);
props.setProperty("mail.transport.protocol", protocol);
props.setProperty("mail.smtp.auth", "true");
//设置初始化发送邮箱对象的加密方法
//配置ssl访问
if (SSL.toLowerCase().equals("true") && TLS.toLowerCase().equals("false")) {
props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
// 只处理SSL的连接,对于非SSL的连接不做处理
props.setProperty("mail.smtp.socketFactory.fallback", "false");
props.setProperty("mail.smtp.socketFactory.port", emailPort);
//注意 这个也要改为ssl端口
}
//配置tls访问
else if (SSL.toLowerCase().equals("false") && TLS.toLowerCase().equals("true")) {
props.setProperty("mail.smtp.starttls.enable", "true");
props.setProperty("mail.smtp.starttls.required", "true");
props.setProperty("mail.smtp.ssl.trust", hostEmailName);
}
//否则默认无安全配置
Session session = Session.getInstance(props,
new javax.mail.Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(emailSendName, emailSendPwd);
}
});
message = new MimeMessage(session);
try {
message.setFrom(new InternetAddress(emailSendName));
} catch (MessagingException e) {
e.printStackTrace();
}
}
//添加新任务时发送邮箱模板
public String sendNew(String taskNum, String url, String assignerAddress, String assignerToAddress) {
try {
message.setSentDate(new Date());
if (StringUtils.isNotBlank(assignerToAddress)) {
message.setRecipients(Message.RecipientType.TO,
InternetAddress.parse(assignerToAddress));
}
if (StringUtils.isNotBlank(assignerAddress)) {
message.setRecipients(Message.RecipientType.CC,
InternetAddress.parse(assignerAddress));
}
if (StringUtils.isBlank(assignerToAddress) && StringUtils.isBlank(assignerAddress)) {
return NOFIND;
}
message.setSubject(" Title"); //标题
message.setContent("####","text/html;charset=gbk");//内容
Transport.send(message);
if (StringUtils.isBlank(assignerToAddress)) {
return NOFIND;
}
} catch (MessagingException e) {
return FAILCODE;
}
return SUCCESSCODE;
}
//任务执行人发生改变时发送邮箱模板
public String sendChange(String taskNum, String url, String assignerToAddress, String... assignerAddress) {
try {
if (StringUtils.isNotBlank(assignerToAddress)) {
message.setRecipients(Message.RecipientType.TO,
InternetAddress.parse(assignerToAddress));
}
if (assignerAddress != null && assignerAddress.length > 0) {
int len = 0;
int index = 0;
for (int i = 0; i < assignerAddress.length; i++) {
if(StringUtils.isNotBlank(assignerAddress[i])){
++len;
}
}
if(len>0){
InternetAddress[] addrs = new InternetAddress[len];
for (int i = 0; i < assignerAddress.length; i++) {
if(StringUtils.isNotBlank(assignerAddress[i])){
addrs[index] = new InternetAddress(assignerAddress[i]);
++index;
}
}
message.setRecipients(Message.RecipientType.CC,
addrs);
}
}else if (StringUtils.isBlank(assignerToAddress)) {
return NOFIND;
}
message.setSubject(" Title"); //标题
message.setContent(
"#####","text/html;charset=gbk");//内容
Transport.send(message);
if (StringUtils.isBlank(assignerToAddress)) {
return NOFIND;
}
} catch (MessagingException e) {
return FAILCODE;
}
return SUCCESSCODE;
}
}
`
配置文件内容:
emailSendName=******@qq.com
emailSendPwd=**ybcecudbbee
emailPort=465
SSL=true
TLS=false
emailProtocol=smtp //该配置指明连接协议smtp/tls等 刚开始没搞懂因为没有配置这个,邮箱一直发送不了报异常
//如
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
认证不通过由于我的是TLS1.2后面配置:
hostEmailName=smtp.*.com
emailSendName=******@*.com
emailSendPwd=**
emailPort=465
SSL=false
TLS=true
**emailProtocol=TLS1.2**
解决办法是:
到这里有两种解决方案:
1.在网上找个生成安全证书的方法按要求放在指定位置:http://www.oschina.net/question/12_19249
2.把当前smtp host设为可信任 props.put(“mail.smtp.ssl.trust”, “smtp服务器地址”)
我采用第二种办法后面测试可行,这个搞了两三天终于调试完成,不过也学会了很多