【Java】java轻量级电子邮件类smtpmail(不是JavaMail),支持附件
用法:1、初始化。smtpmail sm=new smtpmail();
sm.SetServer(服务器地址,端口号,用户名,密码,发件人,收件人);2、发送简单的纯文本邮件:sm.SendTextMail(是否使用SSL加密,如果不使用SSL加密是不是服务器必须支持TLS加密才继续发送,标题,内容);3、发送复杂的邮件:try
{
sm.StartSendMail(是否使用SSL加密,如果不使用SSL加密是不是服务器必须支持TLS加密才继续发送,标题,有没有附件);
sm.SendPlainText(纯文本内容);
sm.SendHTML(HTML格式的内容);
sm.SendAttachment(附件的MIME类型,附件名,文件名,附件内容字节数组);
sm.FinishSendMail();
}
catch(IOException e)
{
e.printStackTrace();
}4、调试:int 最后收到的状态码 = sm.GetLastStatus();
String 最后发送的内容 = sm.GetLastSend();
String 最后收到的内容 = sm.GetLastRecv();
String 最后发送的内容和最后收到的内容 = sm.GetLastSendRecv();5、杂项
[*]使用SSL加密的时候,你需要在smtpmail类的文件夹下村一个SMTP服务器的数字签名文件。否则握手失败——抛出HandShakeException。
举个例子,我要使用QQ的smtp服务器,获取它数字签名的方法是用浏览器进入https://mail.qq.com然后在浏览器的“锁”标识找到证书,并将其复制到文件。
然后在弹出的窗口里找到“详细信息”选项卡,点开,点“复制到文件”按钮。
然后跟着向导走一遍就行了。向导的话详细的自己看着办吧。
[*]不使用SSL加密或者STARTTLS加密的电子邮箱服务器基本上已经不存在了。
[*]这个类只需要实体化一遍就可以随便使用。只需要在发送前保证SetServer填的那些内容都对就行了。
源码:import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.util.UUID;
import java.util.Base64;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
/**
* Created by 0xAA55 on 2015/12/7.
* Author: 0xAA55
* Website: http://www.0xaa55.com
*/
public class smtpmail
{
final private String nl="\r\n";//换行符
final private String nlnl=nl+nl;//换行符
private String m_Sep;//分隔符
//服务器
private String m_ServerAddr;
private int m_ServerPort;
//用户账号
private String m_Username;
private String m_Password;
//发送者和接收者
private String m_MailFrom;
private String m_RcptTo;
//状态
private String m_LastSend;
private String m_LastRecv;
private int m_LastStatus;
//读写器
private Socket m_s;
private BufferedReader m_br;
private PrintStream m_ps;
//=========================================================================
//方法:ConnectToServer
//描述:连接到服务器
private void ConnectToServer()throws IOException
{
m_s=new Socket(m_ServerAddr,m_ServerPort);
m_br=new BufferedReader(new InputStreamReader(m_s.getInputStream()));
m_ps=new PrintStream(m_s.getOutputStream());
}
//=========================================================================
//方法:SSLConnectToServer
//描述:使用SSL加密连接到服务器
private void SSLConnectToServer()throws IOException
{
SSLSocket ss=(SSLSocket)((SSLSocketFactory)SSLSocketFactory.getDefault())
.createSocket(m_ServerAddr,m_ServerPort);
ss.setEnableSessionCreation(true);
ss.setUseClientMode(true);
ss.startHandshake();
m_s=ss;
m_br=new BufferedReader(new InputStreamReader(ss.getInputStream()));
m_ps=new PrintStream(ss.getOutputStream());
}
//=========================================================================
//方法:TurnToSSL
//描述:转为SSL安全连接
private void TurnToSSL()throws IOException
{
SSLSocket ss=(SSLSocket)((SSLSocketFactory)SSLSocketFactory.getDefault())
.createSocket(m_s,m_ServerAddr,m_ServerPort,true);
ss.setEnableSessionCreation(true);
ss.setUseClientMode(true);
//STARTTLS没有握手
//ss.startHandshake();
m_s=ss;
m_br=new BufferedReader(new InputStreamReader(ss.getInputStream()));
m_ps=new PrintStream(ss.getOutputStream());
}
//=========================================================================
//方法:SendSMTPData
//描述:发送SMTP数据
private void SendSMTPData(String command)throws IOException
{
m_ps.print(command);
m_LastSend=command;
// Log.d("smtpmail","Send:"+m_LastSend.replace(nl,""));
System.out.println("Send:"+m_LastSend);
}
//=========================================================================
//方法:RecvSMTPData
//描述:获取一条服务器返回的内容,取得状态码
private int RecvSMTPData()throws IOException
{
//从服务器读取一行返回的内容
m_LastRecv=m_br.readLine();
// Log.d("smtpmail","Recv:"+m_LastRecv);
System.out.println("Recv:"+m_LastRecv);
if(m_LastRecv == null || m_LastRecv.length() == 0)//如果没有取得内容,则抛出错误
throw new IOException("RecvSMTPData: no status code.");
//分析字符串,从前面取得状态码
char[]ch=m_LastRecv.toCharArray();
int i;
m_LastStatus=0;
for(i=0;i<m_LastRecv.length();i++)
{
//读取数字直到遇到别的字符
if(ch>='0'&&ch<='9')
m_LastStatus=m_LastStatus*10+ch-'0';
else
break;
}
if(i==0)//如果没有取得内容,则抛出错误
throw new IOException("RecvSMTPData: no status code.");
return m_LastStatus;
}
//=========================================================================
//方法:StartTls
//描述:发送STARTTLS,然后获取服务器的支持情况
private boolean StartTls()throws IOException
{
//发送STARTTLS
SendSMTPData("STARTTLS"+nl);
//接收到220时表示STARTTLS成功,而接收到的值超过300的就表示失败
do
{
if(RecvSMTPData()==220)
return true;
}while(m_LastStatus<300);
return false;
}
//=========================================================================
//方法:AuthLogin
//描述:验证用户名和密码
private boolean AuthLogin()throws IOException
{
//发送AUTH LOGIN,然后接收服务器返回
SendSMTPData("AUTH LOGIN "+nl);
//略过所有的2xx返回内容
do
RecvSMTPData();
while(m_LastStatus<300);
//得到3xx状态后,发送账号密码
if(m_LastStatus<400)
{
//一次性完成账号和密码的发送
SendSMTPData(Base64.getEncoder().encodeToString(m_Username.getBytes())+nl+
Base64.getEncoder().encodeToString(m_Password.getBytes())+nl);
}
else
return false;//服务器并没有要求输入用户名和密码(或者,530,必须先STARTTLS)
//发送完账号和密码,等服务器返回结果
for(;;)
{
RecvSMTPData();//接收内容
if(m_LastStatus<300)return true;//验证成功
if(m_LastStatus>=400)return false;//其它情况
}
}
//=========================================================================
//方法:SetFromTo
//描述:设置发件人和收件人。要求之前服务器返回的数据都已完成读取
private boolean SetFromTo()throws IOException
{
SendSMTPData("MAIL FROM:<"+m_MailFrom+">"+nl);
//250 OK
//501 mail from address must be same as authorization user
if(RecvSMTPData()>=300)return false;
SendSMTPData("RCPT TO:<"+m_RcptTo+">"+nl);
//250 OK
//550 Mailbox not found or access denied
if(RecvSMTPData()>=300)return false;
return true;
}
//=========================================================================
//方法:Quit
//描述:告知服务器关闭连接,同时自己也关闭连接
private void Quit()
{
try
{
SendSMTPData("QUIT"+nl);
m_s.close();
}catch(IOException e)
{
e.printStackTrace();
}
}
//=========================================================================
//公开方法
//=========================================================================
//方法:构造
//描述:初始化类
public smtpmail()
{
m_LastSend="";
m_LastRecv="";
m_LastStatus=0;
}
//=========================================================================
//方法:SetServer
//描述:设置服务器
void SetServer(String addr,int port,String user,String pswd,String from,String rcpt)
{
m_ServerAddr=addr;
m_ServerPort=port;
m_Username=user;
m_Password=pswd;
m_MailFrom=from;
m_RcptTo=rcpt;
}
//=========================================================================
//方法:StartSendMail
//描述:开始发送邮件
boolean StartSendMail(boolean SSL,boolean MustUseTls,String Subject,boolean HaveAttachment)throws IOException
{
boolean UseTls=false;
if(SSL)
SSLConnectToServer();
else
ConnectToServer();
//Hello
SendSMTPData("EHLO "+m_ServerAddr+nl);
if(RecvSMTPData()!=220)
{
Quit();
return false;
}
if(!SSL)//如果不是SSL加密,就尝试进行STARTTLS握手
{
if(StartTls())
{
UseTls=true;//成功表示支持使用TLS加密
TurnToSSL();
SendSMTPData("EHLO "+m_ServerAddr+nl);
}
else
{
if(m_LastStatus == 454)//服务器不支持STARTTLS
{
if(MustUseTls)
{
Quit();
return false;//而用户却需要使用STARTTLS
}
}
else//StartTls返回的其它信息,视为错误
{
Quit();
return false;
}
}
}
//验证用户名和密码
//这之前服务器可能会发回很多的我们不需要的内容,通过这个可以把它刷掉
if(!AuthLogin())
{
Quit();
return false;
}
//设置发件人和收件人
if(!SetFromTo())
{
Quit();
return false;
}
SendSMTPData("DATA"+nl);
//354 Enter mail, end with "." on a line by itself
do
{
if(RecvSMTPData()>=400) return false;
}
while(m_LastStatus<300);
m_Sep="_Part_"+UUID.randomUUID().toString();
SendSMTPData("From:<"+m_MailFrom+">"+nl+
"To:<"+m_RcptTo+">"+nl+
"Subject: =?UTF-8?B?"+
Base64.getEncoder().encodeToString(Subject.getBytes("UTF-8"))+"?="+nl+
"MIME-Version: 1.0"+nl+
"Content-Type: multipart/"+(HaveAttachment?"mixed;":"alternative;")+" boundary=\""+m_Sep+"\""+nlnl);
return true;
}
//=========================================================================
//方法:SendPlainText
//描述:发送纯文本
void SendPlainText(String Text)throws IOException
{
SendSMTPData("--"+m_Sep+nl+
"Content-Type:text/plain; charset=utf-8"+nl+
"Content-transfer-encoding: Base64"+nl+nl+
Base64.getEncoder().encodeToString(Text.getBytes("UTF-8"))+nlnl);
}
//=========================================================================
//方法:SendHTML
//描述:发送HTML格式的内容
void SendHTML(String TextHTML)throws IOException
{
SendSMTPData("--"+m_Sep+nl+
"Content-Type:text/html; charset=utf-8"+nl+
"Content-transfer-encoding: Base64"+nl+nl+
Base64.getEncoder().encodeToString(TextHTML.getBytes("UTF-8"))+nlnl);
}
//=========================================================================
//方法:SendAttachment
//描述:发送附件
void SendAttachment(String MIMEType,String name,String filename,byte[] data)throws IOException
{
SendSMTPData("--"+m_Sep+nl+
"Content-Type: "+MIMEType+"; name=\"=?UTF-8?B?"+
Base64.getEncoder().encodeToString(name.getBytes("UTF-8"))+"?=\""+nl+
"Content-Transfer-Encoding: Base64"+nl+
"Content-Disposition: attachment; filename=\"=?UTF-8?B?"+
Base64.getEncoder().encodeToString(filename.getBytes("UTF-8"))+"?=\""+nl+nl+
Base64.getEncoder().encodeToString(data)+nlnl);
}
//=========================================================================
//方法:FinishSendMail
//描述:结束邮件的发送
boolean FinishSendMail()throws IOException
{
SendSMTPData("--"+m_Sep+"--"+nl+"."+nl);
//250 2.0.0 tB8BJfTa093352 Message accepted for delivery
if(RecvSMTPData()>=300)
{
Quit();
return false;
}
Quit();
return true;
}
//=========================================================================
//方法:SendTextMail
//描述:发送纯文本邮件
boolean SendTextMail(boolean usessl,boolean MustUseTls,String Subject,String Content)
{
try
{
if(!StartSendMail(usessl,true,Subject,false))
return false;
SendPlainText(Content);
return FinishSendMail();
}
catch(IOException e)
{
e.printStackTrace();
return false;
}
}
//=========================================================================
//方法:Get
int GetLastStatus()
{
return m_LastStatus;
}
String GetLastSend()
{
return m_LastSend;
}
String GetLastRecv()
{
return m_LastRecv;
}
String GetLastSendRecv()
{
return "Last send:"+m_LastSend+"\nLast recv:"+m_LastRecv;
}
}SRC & BIN:
相关链接:
http://www.0xaa55.com/thread-1650-1-1.html 感谢分享。。。
页:
[1]