"Java" Pure low-level SMTP implementation mail send core source code __java

Source: Internet
Author: User
Tags auth base64 flush readline

Source of information: Software talent net Author: bristling super

2002 I wrote an article on the Java implementation of the mail sent, when I wrote the message to send the function is very simple, can not bring attachments, can not have template. Later, a lot of friends asked me, there is no more perfect version, the existing mail sent me to write the design idea is convenient to send the attachment, you can send HTML pages including built-in pictures, styles, and added a message in the HTML Elements background image function (this feature is not in Outlook), There is a mail connection pool framework, and so on, I now use a very perfect, the function is also strong version of the core source code announced below, hoping to allow more technical personnel to master the Java Mail send the underlying technology, what problems can be posted in the Software Talent Network Forum.

Note: Base64 is an encoding method, which mainly encodes binary data into text ASCII encoding and facilitates text transmission. Mail body can have a variety of coding methods, Base64 is a common one.

Package com.sunstudio.pool.mail;


Import java.io.*;
Import java.net.*;
Import java.util.*;
Import sun.misc.*;
Import com.sigmaproject.config.*;
Import com.sigmaproject.util.*;
Import com.sigmaproject.stream.*;
Import com.sunstudio.pool.*;


public class Mailconnection extends poolconnection{

public static String Crlf=system.getproperty ("Line.separator");
public static String crlftab=crlf+ "/t";

public static string[] Tpl_start_flag=new string[]{
"Background=/" ",
"Src=/" ",
"Background= '",
"Src= '"
};
public static string[] Tpl_end_flag=new string[]{
"/"",
"/"",
"'",
"'"
};

public static String tpl_inner_name= "F";

public transient static final int low_priority = 5;
public transient static final int normal_priority = 3;
public transient static final int high_priority = 1;

public static Base64encoder encoder=new Base64encoder ();

Socket Socket=null;
Pureoutputstream Outdata=null;
Pureinputstream Indata=null;
Boolean connected=false;
Boolean destoryed=false;
Boolean use_template=false;


String Smtpserver=null;
String Smtpport=null;
String Fromuser=null;
String Pass=null;
String Fromname=null;
Boolean isneedauthlogin=false;
Boolean returnreceipt=false;
String subject= "";
String textcontent= "";
String htmlcontent= "";
Hashtable tos=new Hashtable ();
Vector attach0=new vector ();
Vector attach1=new vector ();
int priority=3;

Public mailconnection (ConnectionPool pool1,string serveraddr,string serverport,string user_email,string) {
Super (Pool1,conn_type_mail);
SMTPSERVER=SERVERADDR;
Smtpport=serverport;
User_email= (user_email==null| | User_email.equals ("")? Unknown ": user_email);
int S1=user_email.indexof ("<");
if (s1==-1) {
Fromuser=user_email;
Fromname=user_email;
}else{
Fromuser=user_email.substring (S1+1,user_email.indexof (">"));
Fromname=user_email.substring (0,S1);
}
Pass=password;
}
/** use templates to send messages
*
* Note: When writing the content of the template and the content of the message body to pay attention to a certain format, when the use of built-in files, the need for special annotations to facilitate the replacement of components and processing;
* Use the mail template to send another additional attachment, but no longer specify the content of the message, that is, it is best not to call the Sethtmlcontent method, or Innerattach will be invalidated
*/
public void Usetemplate (String tpl,string source_path) {
Attach0.removeallelements ();
Attach1.removeallelements ();
Tpl=tpl.tolowercase ();//mail cannot use JavaScript basics, so you can do pure HTML
Vector s1=new vector (), d1=new vector ();
int a=-1,b=-1,spos=0,x=0;
String Fa=null,fb=null,s=null,e=null,f=null;
File Ftmp=null;
for (int i=0;i<tpl_start_flag.length;i++,spos=0) {
S=tpl_start_flag[i];
E=tpl_end_flag[i];
while (true) {
if ((A=tpl.indexof (S,spos)) <0) break;//did not find the start flag
if ((B=tpl.indexof (E,a+s.length ())) <0) break;//no end flag found
Fa=tpl.substring (A+s.length (), b);
Spos=b+e.length ();
if (S1.contains (f=s+fa+e)) continue;
if (!) ( Ftmp=new File (SOURCE_PATH,FA)). Exists ()) continue;
fb=tpl_inner_name+x++;
S1.addelement (f);
D1.addelement (s+ "CID:" +fb+e);
Addinnerattach (new Attachment (FTMP,FB));
Ftmp=null;
}
}
Sethtmlcontent (Stringex.replace (TPL,S1,D1));
Use_template=true;
}
public void Setreturnreceipt (Boolean s) {returnreceipt=s}
public void setpriority (int s) {priority=s}
public void Settextcontent (String s) {if (s==null) return;textcontent=s;}
public void Sethtmlcontent (String s) {if (s==null) return;htmlcontent=s;}
public void Setsubject (String s) {subject= (s==null| | S.equals ("")? ": s);}
public boolean Addmailto (String toname1,string toemail) {return tos.put (toemail,toname1)!=null;}
public boolean Addmailto (String user_email) {
int S1=user_email.indexof ("<");
String name1= "";
String email1= "";
if (s1<0) {
Name1=user_email;
Email1=user_email;
}else{
Email1=user_email.substring (S1+1,user_email.indexof (">"));
Name1=user_email.substring (0,S1);
}
Return Tos.put (email1,name1)!=null;
}
public void Addinnerattach (attachment att) {attach0.addelement (ATT);}
public void Addattach (attachment att) {attach1.addelement (ATT);}
public Boolean connect () {
try{
Fromname= (fromname==null "": fromname);
Isneedauthlogin= (Fromuser!=null&&pass!=null&&!fromuser.equals ("") &&!pass.equals (""));
Socket=new Socket (Smtpserver,integer.parseint (Smtpport));
Outdata=new Pureoutputstream (New Bufferedoutputstream (Socket.getoutputstream ()));
Indata=new Pureinputstream (Socket.getinputstream ());
Readresponse ("220");
Sendrequestresponse ("HELO", "+smtpserver+crlf");
if (Isneedauthlogin) {
Sendrequestresponse ("334", "AUTH login" +crlf);//auth Login
Sendrequestresponse ("334", New String (Encoder.encode (Fromuser.getbytes ()) +CRLF);//username:
Sendrequestresponse ("235", New String (Encoder.encode (Pass.getbytes ()) +CRLF);//password:
}
Connected=true;
}catch (Exception e) {
E.printstacktrace ();
Connected=false;
Destory ();
}
System.out.println ("Mail server Connection" +connected);
return connected;
}
public Boolean send () {
try{
Note: 163 mailbox does not allow the mail person name and the mail person address same
Sendrequestresponse ("RSET", "+crlf");
Sendrequestresponse ("A", "Mail from:" + "<" +fromuser+ ">" +CRLF);/command does not need to have a mail person name, remember!!!!!
For (enumeration Enu=tos.keys (); enu.hasmoreelements ();) {
Object to1=enu.nextelement ();
if (to1==null) continue;
String touser= (String) to1;
String Toname= (String) tos.get (to1);
Sendrequestresponse ("250,550", "RCPT to:" + "<" +touser+ ">" +CRLF);/command does not need to have a mail person name, remember!!!!!
}
Sendrequestresponse ("354", "DATA" +CRLF);
if (!sendbody ()) throw new Exception ("Error sending message content!");
Sendrequestresponse ("crlf+", "".) +CRLF);
return true;
}catch (Exception e) {
E.printstacktrace ();
Destory ();
}
return false;
}
public boolean isavailable () {
while (!connected) {
Connect ();
Try{thread.currentthread (). Sleep (100);} catch (Exception e) {}
}
Return Socket!=null
&&connected
&&!destoryed
&&!socket.isclosed ()
&&!socket.isoutputshutdown ()
&&!socket.isinputshutdown ();
}
public void Close () {
try{
Returnreceipt=false;
Subject= "";
Textcontent= "";
Htmlcontent= "";
Tos.clear ();
Attach0.clear ();
Attach1.clear ();
Sendrequestresponse ("RSET", "+crlf");
}catch (Exception e) {
Destory ();
}
}
public void Destory () {
try{
Sendrequestresponse ("221", "QUIT" +crlf)//quit exit
}catch (Exception e) {}
try{
Closesocket ();
}catch (Exception e) {}
Destoryed=true;
}
public Boolean isdestory () {
return destoryed;
}
private void Closesocket () {
Try{if (indata!=null) {indata.close (); indata=null;}} catch (Exception ex) {}
Try{if (outdata!=null) {outdata.close (); outdata=null;}} catch (Exception ex) {}
Try{if (socket!=null) {socket.close (); socket=null;}} catch (Exception ex) {}
}
private string Getgbkencodestr (String x) {
Return "=?gb2312?" B? " +base64.encodestring (X==null "": x) + "? =";
}
private void Readresponse (String cmd) throws exception{
String Tmp=indata.readline ();
String code=tmp.substring (0,3);
System.out.println ("S:" +tmp);
if (("," +cmd+ ","). IndexOf (code) >-1);
else throw new Exception ("######### #邮件发送失败!##########" +tmp+ "(" +cmd+ ")");
while (Tmp.startswith (cmd+ "-")) Tmp=indata.readline ();
}
private void SendRequest (String msg) throws exception{
System.out.println ("C:" +msg);
Outdata.print (msg);
Outdata.flush ();
}
private void Sendrequestresponse (String cmd,string msg) throws exception{
SendRequest (msg);
Readresponse (CMD);
}
Private Boolean sendbody () {
String boundary0= "----=hawa_multipart_mixed_" +md5.encode (string.valueof (Math.random () +1));
String boundary1= "----=hawa_multipart_related_" +md5.encode (string.valueof (Math.random () +2));
String boundary2= "----=hawa_multipart_alternative_" +md5.encode (string.valueof (Math.random () +3));
try{
Message header information Area////////////////////////////
Outdata.print ("Date:" +new date (). toGMTString () +CRLF);
Outdata.print ("From:" + "/" "+getgbkencodestr (fromname) +"/"<" +fromuser+ ">" +crlf);
Outdata.print ("to:");
int tmp=0;
String To1=null;
For (enumeration Enu=tos.keys (); enu.hasmoreelements ();) {
to1= (String) enu.nextelement ();
Outdata.print (tmp==0? ":", "+crlftab" + "/" "+getgbkencodestr ((String) Tos.get (to1)) +"/"<" +to1+ ">");
tmp++;
}
Outdata.print (CRLF);
Outdata.print ("Subject:");
for (int i=0;i<subject.length (); i+=26) {
if (i>0) outdata.print (Crlftab);
Outdata.print (Getgbkencodestr (subject.substring (I,math.min (Subject.length (), i+26)));
}
Outdata.print (CRLF);

Outdata.print ("Message-id: <" +system.currenttimemillis () +fromuser.substring (Fromuser.indexof ("@")) + ">" + CRLF);
Outdata.print ("x-priority:" +priority+crlf);
Outdata.print ("X-mailer:hawa Java Mailer" +crlf);
Read Receipts
if (returnreceipt) outdata.print ("disposition-notification-to:" + "/" "+getgbkencodestr (fromname) +"/"<" +fromUser + ">" +crlf);
Outdata.print ("mime-version:1.0" +CRLF);
Outdata.print ("content-type:multipart/mixed;boundary=/" "+boundary0+"/"" +CRLF);
Outdata.print (CRLF);
Message body data area (delimiter definition)///////////////////////////////////////////////////////////////////
Outdata.print ("This are a multi-part message in MIME format.") +CRLF);
Outdata.print ("--" +BOUNDARY0+CRLF);
Outdata.print ("content-type:multipart/related;type=/" multipart/alternative/";" +crlftab+ "boundary=/" "+boundary1+"/"" +CRLF);
Outdata.print (CRLF);
Outdata.print ("//alternative Boundaryid" +crlf);
Outdata.print ("--" +BOUNDARY1+CRLF);
Outdata.print ("content-type:multipart/alternative;") +crlftab+ "boundary=/" "+boundary2+"/"" +CRLF);
Outdata.print (CRLF);
Message Plain Text///////////////////////////////////////////////////////
Outdata.print ("//alternative plaintext" +CRLF);
Outdata.print ("--" +BOUNDARY2+CRLF);
Outdata.print ("Content-type:text/plain;") +crlftab+ "charset=/" gb2312/";" +CRLF);
Outdata.print ("Content-transfer-encoding:base64" +CRLF);
Outdata.print ("Content-disposition:inline" +CRLF);
Outdata.print (CRLF);
Outdata.print (Encoder.encode (Textcontent.getbytes ()) +CRLF);
Outdata.print (CRLF);
Mail HTML text///////////////////////////////////////////////////////
Outdata.print ("//alternative html" +CRLF);
Outdata.print ("--" +BOUNDARY2+CRLF);
Outdata.print ("content-type:text/html;") +crlftab+ "charset=/" gb2312/"" +CRLF);
Outdata.print ("Content-transfer-encoding:base64" +CRLF);
Outdata.print ("Content-disposition:inline" +CRLF);
Outdata.print (CRLF);
Outdata.print (Encoder.encode (Htmlcontent.getbytes ()) +CRLF);
Outdata.print (CRLF);
Outdata.print ("--" +boundary2+ "--" +CRLF);
Outdata.print (CRLF);
Mail HTML link Content-id (mainly contains image and style)///////////////////////////////////////////////////////
For (enumeration enu=attach0.elements (); enu.hasmoreelements ();) ((attachment) enu.nextelement ()). WriteToMail ( OUTDATA,BOUNDARY1);
Outdata.print ("--" +boundary1+ "--" +CRLF);
Outdata.print (CRLF);
Mail Attachment///////////////////////////////////////////////////////
For (enumeration enu=attach1.elements (); enu.hasmoreelements ();) ((attachment) enu.nextelement ()). WriteToMail ( OUTDATA,BOUNDARY0);
Outdata.print ("--" +boundary0+ "--" +CRLF);
//////////////////////////////////////////////////////////
Outdata.flush ();
}catch (Exception e) {
return (Connected=false);
}
return true;
}
public static string GetMimeType (string filename) {
if (filename==null| | Filename.equals ("") | | Filename.indexof (".") ==-1) return ("Application/octet-stream");
String ext=filename.substring (Filename.lastindexof (".")). toLowerCase ();
String ret=systemconfig.getparameter (EXT);
if (ret==null| | Ret.equals ("")) Return ("Application/octet-stream");
return ret;
}
}

Software Talent Network http://www.soft-hr.cn welcome you.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.