smtp
使用ESMTP/SMTP进行邮件发送,遇到一个问题:
假如附件为图片gif文件,发送没有问题。但是接收后,无法显示图片。敬请高手指点!!!!!
/*
* Created on 2004-12-21
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/
/**
* @author Administrator
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class FoxMailMain {
public static void main(String[] args) {
FoxMail foxMail = new FoxMail("smtp.citiz.net",25);
foxMail.setMailUserName("zhou");
foxMail.setMailUserPass("abcdefgf");
foxMail.setMailTo("aaaaa@citiz.net");
foxMail.setMailFrom("bbbb@citiz.net");
foxMail.setMailShowTo("tom");
foxMail.setMailShowFrom("Nike");
foxMail.setMailSubject("hello用中文主题");
foxMail.setMailBody("welcome for you. mmm.中文呀.aaa \r\n载来一行");
foxMail.setMailAttachFile(new String[] {"D:\\eclipse_project\\workspace\\PROJECT_email\\src\\pic.gif"});
if(foxMail.sendMail()){
System.out.println("OK.");
}else{
System.out.println("False.");
}
}
}
FoxMail.java 代码
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
/*
* Created on 2004-12-21
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/
/**
* @author Administrator
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class FoxMail {
private final static byte LOCATION_TO_SCREEN = 1;//Log信息输出位置 1=输出到屏幕
private final static DateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//日志用日期格式
private final static String END_FLAG = "\r\n";//SMTP/ESMTP命令结束标记
private final static String EMAIL_ATTACH_SIGN = "=====att";//邮件附件的表示符号
private String smtpServer = null;//邮件发送服务器域名
private int smtpPort = 25;//邮件发送端口
private Socket clientMailSocket;//邮件连接socket
private InputStream inData;//接收数据
private OutputStream outData;//发送数据
private String mailUserName = null;//邮件账户
private String mailUserPass = null;//邮件账户的密码
private String mailTo = null;//邮件发送目标
private String mailFrom = null;//邮件发送人
private String mailSubject = null;//邮件主题
private String mailBody = null;//邮件正文
private String mailShowTo = null;//邮件内容抬头部分-邮件发送目标
private String mailShowFrom = null;//邮件内容抬头部分-邮件发送人
private String[] mailAttachFile = null;//邮件附件对应的本地文件名(包含绝对路径)
/**
* @return Returns the mailAttachFile.
*/
public String[] getMailAttachFile() {
return mailAttachFile;
}
/**
* @param mailAttachFile The mailAttachFile to set.
*/
public void setMailAttachFile(String[] mailAttachFile) {
this.mailAttachFile = mailAttachFile;
}
/**
* @return Returns the mailShowFrom.
*/
public String getMailShowFrom() {
return mailShowFrom;
}
/**
* @param mailShowFrom The mailShowFrom to set.
*/
public void setMailShowFrom(String mailShowFrom) {
this.mailShowFrom = mailShowFrom;
}
/**
* @return Returns the mailShowTo.
*/
public String getMailShowTo() {
return mailShowTo;
}
/**
* @param mailShowTo The mailShowTo to set.
*/
public void setMailShowTo(String mailShowTo) {
this.mailShowTo = mailShowTo;
}
/**
* @return Returns the mailBody.
*/
public String getMailBody() {
return mailBody;
}
/**
* @param mailBody The mailBody to set.
*/
public void setMailBody(String mailBody) {
this.mailBody = mailBody;
}
/**
* @return Returns the mailFrom.
*/
public String getMailFrom() {
return mailFrom;
}
/**
* @param mailFrom The mailFrom to set.
*/
public void setMailFrom(String mailFrom) {
this.mailFrom = mailFrom;
}
/**
* @return Returns the mailSubject.
*/
public String getMailSubject() {
return mailSubject;
}
/**
* @param mailSubject The mailSubject to set.
*/
public void setMailSubject(String mailSubject) {
this.mailSubject = mailSubject;
}
/**
* @return Returns the mailTo.
*/
public String getMailTo() {
return mailTo;
}
/**
* @param mailTo The mailTo to set.
*/
public void setMailTo(String mailTo) {
this.mailTo = mailTo;
}
/**
* @return Returns the mailUserName.
*/
public String getMailUserName() {
return mailUserName;
}
/**
* @param mailUserName The mailUserName to set.
*/
public void setMailUserName(String mailUserName) {
this.mailUserName = mailUserName;
}
/**
* @return Returns the mailUserPass.
*/
public String getMailUserPass() {
return mailUserPass;
}
/**
* @param mailUserPass The mailUserPass to set.
*/
public void setMailUserPass(String mailUserPass) {
this.mailUserPass = mailUserPass;
}
/**
* Constrctor
* @param _smtpServer
* @param _smtpPort
*/
public FoxMail(String smtpServer,int smtpPort){
this.smtpServer = smtpServer;
this.smtpPort = smtpPort;
}
/**
* 写日志信息
* @param _log
* @param _locaton
*/
public static void printLogger(String _log,int _locaton){
switch(_locaton){
case LOCATION_TO_SCREEN:
System.out.println("["+dateformat.format(new Date()) + "] " + _log);
break;
default:
System.out.println("["+dateformat.format(new Date()) + "] " + _log);
}//switch(_locaton)
}//end
/**
*
* @return
*/
public boolean createConnection(){
try {
freeAll();
clientMailSocket = new Socket(smtpServer, smtpPort);
printLogger("Connect to email server " + smtpServer + " on port " + smtpPort,LOCATION_TO_SCREEN);
inData = clientMailSocket.getInputStream();
outData = clientMailSocket.getOutputStream();
fetchCMDResult();//当首次连接服务器后有返回值,必须取走该返回值,否则后面命令的返回值无法判断
} catch (IOException e) {
return false;
}
return true;
}
public static String response(InputStream in){
byte[] buffer = new byte[1024];
StringBuffer inData = new StringBuffer();
int n = 0;
try {
n = in.read(buffer);
inData.append(new String(buffer, 0, n));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
printLogger("CMDResult=" + inData.toString(),LOCATION_TO_SCREEN);
return inData.toString();
}
public static void send(String s, OutputStream out){
byte[] buffer = s.getBytes();
try {
out.write(buffer);
out.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public String fetchCMDResult(){
return response(inData);
}
public boolean sendCmd(String _cmd) {
if (_cmd != null) {
send(_cmd,outData);
printLogger("CMD=" + _cmd,LOCATION_TO_SCREEN);
}
return true;
}
/**
* 发送邮件
* 服务器为ESMTP时候采用本方法
* @return true=send ok,false=send failed
*/
public boolean sendMail() {
//打开与邮件服务器的连接
if(!createConnection()){
return false;
}
StringBuffer theContent = null;
//EHLO
theContent = new StringBuffer();
theContent.append("EHLO ");
theContent.append(smtpServer);
theContent.append(END_FLAG);
sendCmd(theContent.toString());
if(fetchCMDResult().indexOf("250")==-1) return false;
//AUTH LOGIN
theContent = new StringBuffer();
theContent.append("AUTH LOGIN");
theContent.append(END_FLAG);
sendCmd(theContent.toString());
if(fetchCMDResult().indexOf("334")==-1) return false;
//用户名
theContent = new StringBuffer();
theContent.append(Base64Encode(this.mailUserName));
theContent.append(END_FLAG);
sendCmd(theContent.toString());
if(fetchCMDResult().indexOf("334")==-1) return false;
//密码
theContent = new StringBuffer();
theContent.append(Base64Encode(this.mailUserPass));
theContent.append(END_FLAG);
sendCmd(theContent.toString());
if(fetchCMDResult().indexOf("235")==-1) return false;
//邮件发送者
theContent = new StringBuffer();
theContent.append("MAIL FROM:");
theContent.append("<");
theContent.append(this.mailFrom);
theContent.append(">");
theContent.append(END_FLAG);
sendCmd(theContent.toString());
if(fetchCMDResult().indexOf("250")==-1) return false;
//邮件发送目标地址
theContent = new StringBuffer();
theContent.append("RCPT TO:");
theContent.append("<");
theContent.append(this.mailTo);
theContent.append(">");
theContent.append(END_FLAG);
sendCmd(theContent.toString());
if(fetchCMDResult().indexOf("250")==-1) return false;
//邮件内容-开始
theContent = new StringBuffer();
theContent.append("DATA");
theContent.append(END_FLAG);
sendCmd(theContent.toString());
if(fetchCMDResult().indexOf("354")==-1) return false;
//邮件内容-邮件抬头部分
theContent = new StringBuffer();
theContent.append("From:");
theContent.append(this.mailShowFrom);
theContent.append(END_FLAG);
theContent.append("To:");
theContent.append(this.mailShowTo);
theContent.append(END_FLAG);
theContent.append("Subject:");
theContent.append(this.mailSubject);
theContent.append(END_FLAG);
theContent.append("Mime-Version: 1.0");
theContent.append(END_FLAG);
theContent.append("Content-Type: multipart/mixed;Boundary=\"");//设置附件表示符
theContent.append(EMAIL_ATTACH_SIGN);
theContent.append("\"");
theContent.append(END_FLAG);//在正文内容前必须有2个END_FLAG标记
theContent.append(END_FLAG);
sendCmd(theContent.toString());
//邮件内容-正文部分
theContent = new StringBuffer();
theContent.append("--");
theContent.append(EMAIL_ATTACH_SIGN);
theContent.append(END_FLAG);
theContent.append("Content-type:text/plain;");
theContent.append(END_FLAG);
theContent.append("Content-Transfer-Encoding: base64");
theContent.append(END_FLAG);
theContent.append(END_FLAG);
theContent.append(Base64Encode(this.mailBody));
theContent.append(END_FLAG);
theContent.append(END_FLAG);
sendCmd(theContent.toString());
//邮件内容-附件部分
//mailAttachFile = null;
if(mailAttachFile!=null && mailAttachFile.length>0){
for(int i=0;i<this.mailAttachFile.length;i++){
//发送附件抬头
theContent = new StringBuffer();
theContent.append("--");
theContent.append(EMAIL_ATTACH_SIGN);
theContent.append(i);
theContent.append(END_FLAG);
theContent.append("Content-Type:image/gif;name=\"aaa.gif\"");
theContent.append(END_FLAG);
theContent.append("Content-Transfer-Encoding:base64");
theContent.append(END_FLAG);
theContent.append("Content-Disposition:attachment;name=\"aaa.gif\"");
theContent.append(END_FLAG);
theContent.append(END_FLAG);
sendCmd(theContent.toString());
//发送附件内容
sendBase64Data(new StringBuffer(Base64Encode(readFile(mailAttachFile[i]))));
//发送附件结束
/*
theContent = new StringBuffer();
theContent.append(END_FLAG);
theContent.append("--");
theContent.append(EMAIL_ATTACH_SIGN);
theContent.append(i);
theContent.append("--");
theContent.append(END_FLAG);
sendCmd(theContent.toString());
*/
}
}
//发送附件结束
theContent = new StringBuffer();
theContent.append(END_FLAG);
theContent.append(END_FLAG);
theContent.append("--");
theContent.append(EMAIL_ATTACH_SIGN);
theContent.append("--");
theContent.append(END_FLAG);
sendCmd(theContent.toString());
//邮件内容-结束标记
theContent = new StringBuffer();
theContent.append(END_FLAG);
theContent.append(".");
theContent.append(END_FLAG);
sendCmd(theContent.toString());
if(fetchCMDResult().indexOf("250")==-1) return false;
//退出断开服务器连接
theContent = new StringBuffer();
theContent.append("QUIT");
theContent.append(END_FLAG);
sendCmd(theContent.toString());
fetchCMDResult();
//邮件发送成功后释放资源
freeAll();
theContent = null;
return true;//邮件发送成功
}
/**
* 发送经过Base64编码后的数据
* @param src
*/
public void sendBase64Data(StringBuffer srcData){
int LEN_CMD_DATA = 76;
int startIndex = 0;
int totalLength = 0;
if(srcData!=null && srcData.length()>0){
totalLength = srcData.length();
while(true){
if(startIndex+LEN_CMD_DATA<totalLength){
sendCmd(srcData.substring(startIndex,startIndex+LEN_CMD_DATA));
sendCmd(END_FLAG);
}else{
sendCmd(srcData.substring(startIndex,totalLength));
sendCmd(END_FLAG);
break;
}
startIndex = startIndex+LEN_CMD_DATA;
}
}
}
/**
* 释放所有资源
*
*/
public void freeAll(){
if(inData!=null){
try {
inData.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
inData = null;
}
if(outData!=null){
try {
outData.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
outData = null;
}
if(clientMailSocket!=null){
try {
clientMailSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
clientMailSocket = null;
}
}
/**
* 读取文件内容
* @param fileName
* @return
*/
public String readFile(String fileName){
byte[] fileBuffer = new byte[1024];
int realSize = 0;
StringBuffer readContent = new StringBuffer();
try {
InputStream inFile = new FileInputStream(new File(fileName));
while(true){
realSize = inFile.read(fileBuffer);
if(-1==realSize) break;
readContent.append(new String(fileBuffer,0,realSize));
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return readContent.toString();
}
/**
* Base64编码函数
* 将指定的字符串编码为Base64格式的字符串
* @param src
* @return
*/
public static String Base64Encode(String src) {
if (src == null || src.length() == 0)
return "";
String EncodingTable = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
byte[] Buffer = src.getBytes();
int ReadNow, i, res;
char[] WriteBuf = new char[4];
char[] Buf = new char[3];
String EncodedStr = "";
int ReadIndex = 0;
int Len = Buffer.length;
boolean isEnd;
int BytesWritten = 0;
ReadNow = 0;
do {
isEnd = false;
for (i = 0; i < 3; i++) {
if (ReadIndex >= Len) {
isEnd = true;
ReadNow = i;
break;
}
Buf[i] = (char) (((byte) Buffer[ReadIndex]) & 0x00FF);
ReadIndex = ReadIndex + 1;
}
if (isEnd)
break;
WriteBuf[0] = EncodingTable.charAt((Buf[0] >> 2) & 0x003F);
WriteBuf[1] = EncodingTable
.charAt(((Buf[0] & 3) << 4 | (Buf[1] >> 4)) & 0x003F);
WriteBuf[2] = EncodingTable
.charAt(((Buf[1] & 15) << 2 | (Buf[2] >> 6)) & 0x003F);
WriteBuf[3] = EncodingTable.charAt((Buf[2] & 63) & 0x003F);
for (i = 0; i < 4; i++)
EncodedStr = EncodedStr + WriteBuf[i];
BytesWritten = BytesWritten + 4;
if ((BytesWritten % 76) == 0) {
EncodedStr = EncodedStr + "";
}
} while (ReadNow != 3);
if (ReadNow < 3) {
switch (ReadNow) {
case 1:
WriteBuf[0] = EncodingTable.charAt((Buf[0] >> 2) & 0x003F);
WriteBuf[1] = EncodingTable
.charAt(((Buf[0] & 3) << 4) & 0x003F);
WriteBuf[2] = '=';
WriteBuf[3] = '=';
for (i = 0; i < 4; i++)
EncodedStr = EncodedStr + WriteBuf[i];
break;
case 2:
WriteBuf[0] = EncodingTable.charAt((Buf[0] >> 2) & 0x003F);
WriteBuf[1] = EncodingTable
.charAt(((Buf[0] & 3) << 4 | (Buf[1] >> 4)) & 0x003F);
WriteBuf[2] = EncodingTable
.charAt(((Buf[1] & 15) << 2) & 0x003F);
WriteBuf[3] = '=';
for (i = 0; i < 4; i++)
EncodedStr = EncodedStr + WriteBuf[i];
break;
default:
break;
}
}
return (EncodedStr);
}
}