JAVAMAIL源代码中包含了对于SMTP发邮件的实现,下面是我的一个简单实现:
1、BASE64编码类:
package mymail;
public class MyBase64Encoder {
public static byte[] encode(byte[] inbuf) {
int size = inbuf.length;
byte[] outbuf = new byte[((size + 2) / 3) * 4];
int inpos, outpos;
int val;
// 情况1:大于等于3
for (inpos = 0, outpos = 0; size >= 3; size -= 3, outpos += 4) {
val = inbuf[inpos++] & 0xff;
val <<= 8;
val |= inbuf[inpos++] & 0xff;
val <<= 8;
val |= inbuf[inpos++] & 0xff;
// 到此val中存储了3*8=24个二进制位,然后分4次,每次6个二进制位输出
outbuf[outpos + 3] = (byte) pem_array[val & 0x3f];
val >>= 6;
outbuf[outpos + 2] = (byte) pem_array[val & 0x3f];
val >>= 6;
outbuf[outpos + 1] = (byte) pem_array[val & 0x3f];
val >>= 6;
outbuf[outpos + 0] = (byte) pem_array[val & 0x3f];
}
// 情况2:等于1或者等于2
if (size == 1) {
val = inbuf[inpos++] & 0xff;
val <<= 4;
// 到此val中实际有效二进制位8+4=12个,并且后4个都为0
outbuf[outpos + 3] = (byte) '='; // pad character;
outbuf[outpos + 2] = (byte) '='; // pad character;
outbuf[outpos + 1] = (byte) pem_array[val & 0x3f];
val >>= 6;
outbuf[outpos + 0] = (byte) pem_array[val & 0x3f];
} else if (size == 2) {
val = inbuf[inpos++] & 0xff;
val <<= 8;
val |= inbuf[inpos++] & 0xff;
val <<= 2;
// 得到此val中实际有效二进制位为8+8+2=18个,并且后2个为0
outbuf[outpos + 3] = (byte) '='; // pad character;
outbuf[outpos + 2] = (byte) pem_array[val & 0x3f];
val >>= 6;
outbuf[outpos + 1] = (byte) pem_array[val & 0x3f];
val >>= 6;
outbuf[outpos + 0] = (byte) pem_array[val & 0x3f];
}
return outbuf;
}
private final static char pem_array[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 0
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 1
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 2
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', // 3
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', // 4
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', // 5
'w', 'x', 'y', 'z', '0', '1', '2', '3', // 6
'4', '5', '6', '7', '8', '9', '+', '/' // 7
};
}
2、具体应用类:
package mymail;
import java.io.File;
import java.io.IOException;
import java.util.Date;
public class MyTest {
public static void main(String[] args) throws IOException {
MyMsg msg = new MyMsg();
msg.setSubject("suject 主题");
msg.setFrom("from@test.com");
msg.setRecipient("test@test.com");
msg.setDate(new Date());
MyBodyPart body = new MyBodyPart();
body.setText("text 邮件正文");
MyBodyPart attach = new MyBodyPart();
attach.attachFile(new File("D:\\My Documents\\music.txt"));
MyMultiPart content = new MyMultiPart();
content.addPart(body);
content.addPart(attach);
msg.setContent(content);
SMTPTrans trans = SMTPTrans.getInstance();
trans.setDebug(true);
trans.connect("127.0.0.1");;
trans.sendMsg(msg);
}
}
输出:
C:EHLO 127.0.0.1
S:220 kinkding-d1d01d SMTP Server (JAMES SMTP Server 2.3.1) ready Sun, 26 Apr 2009 01:05:20 +0800 (CST)
C:MAIL FROM:<from@test.com>
S:250-kinkding-d1d01d Hello 127.0.0.1 (localhost [127.0.0.1])
C:MAIL FROM:<from@test.com>
S:250-PIPELINING
C:RCPT TO:<test@test.com>
S:250 ENHANCEDSTATUSCODES
C:DATA
S:250 2.1.0 Sender <from@test.com> OK
C:.
S:503 5.5.0 Sender already specified
250 2.1.5 Recipient <test@test.com> OK
354 Ok Send data ending with <CRLF>.<CRLF>
C:QUIT
S:250 2.6.0 Message received
3、邮件类:
package mymail;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class MyMsg {
private String subject;
private String from;
private String recipient;
private Date date;
private String newline = "\r\n";
private MyMultiPart content;
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public void setSubject(String subject) {
this.subject = subject;
}
public void setFrom(String from) {
this.from = from;
}
public String getRecipient() {
return recipient;
}
public void setRecipient(String recipient) {
this.recipient = recipient;
}
public String getSubject() {
return subject;
}
public String getFrom() {
return from;
}
public void setContent(MyMultiPart content) {
this.content = content;
}
public void writeTo(OutputStream out) throws IOException {
// 发送日期
SimpleDateFormat sdf = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss '+0800' (z)", Locale.US);
out.write(("Date: " + sdf.format(date) + newline).getBytes());
out.write(("From: " + this.from + newline).getBytes());
out.write(("To: " + this.recipient + newline).getBytes());
// 发送主题
out.write("Subject: =?gb2312?B?".getBytes());
out.write(MyBase64Encoder.encode(this.subject.getBytes()));
out.write(("?=" + newline).getBytes());
// 发送内容
this.content.writeTo(out);
}
}
4、MyMultiPart:
package mymail;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
public class MyMultiPart {
private String boundary;
private String contentType;
private List<MyBodyPart> parts = new ArrayList<MyBodyPart>();
private String newLine = "\r\n";
public MyMultiPart() {
boundary = "----=_Part_0" + this.hashCode() + "_" + System.currentTimeMillis();
contentType = "Content-Type: multipart/mixed;";
}
public void addPart(MyBodyPart part) {
parts.add(part);
}
public void writeTo(OutputStream out) throws IOException {
out.write((this.contentType + "boundary=\"" + this.boundary+ "\"" + newLine).getBytes());
for (MyBodyPart body : parts) {
out.write((newLine+"--" + this.boundary + newLine).getBytes());
body.writeTo(out);
out.write(newLine.getBytes());
out.flush();
}
out.write((newLine+"--" + this.boundary + newLine).getBytes());
}
}
5、MyBodyPart:
package mymail;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
public class MyBodyPart {
private String contentType = "Content-Type: ";
private String transferEncoding = "Content-Transfer-Encoding: base64";
private String contentDisp;
private String newLine = "\r\n";
private String text;
private File file;
public void setText(String str) {
contentType += "text/plain";
text = str;
}
public void attachFile(File f) {
contentType += "application/octet-stream; name=" + f.getName();
contentDisp = "Content-Disposition: attachment; filename=" + f.getName();
file = f;
}
public void writeTo(OutputStream out) throws IOException {
out.write((this.contentType + newLine).getBytes());
out.write((this.transferEncoding + newLine).getBytes());
if (this.text != null) {
// 字符形式
out.write(newLine.getBytes());
this.byteWrite(out, text.getBytes());
} else {
// 文件形式
out.write((this.contentDisp + newLine + newLine).getBytes());
FileInputStream input = new FileInputStream(file);
byte[] content = new byte[0];
byte[] buf = new byte[256];
int len;
while ((len = input.read(buf)) > -1) {
byte[] temp = new byte[content.length];
System.arraycopy(content, 0, temp, 0, content.length);
content = new byte[content.length + len];
System.arraycopy(temp, 0, content, 0, temp.length);
System.arraycopy(buf, 0, content, temp.length, len);
}
this.byteWrite(out, content);
}
}
private void byteWrite(OutputStream out, byte[] bytes) throws IOException {
byte[] encoded = MyBase64Encoder.encode(bytes);
// 每行最多76个字符输出
int maxChar = 76;
int idx = 0;
for (int size = encoded.length / maxChar; idx < size; idx++) {
out.write(encoded, idx * maxChar, maxChar);
out.write(newLine.getBytes());
}
if (encoded.length % maxChar > 0) {
out.write(encoded, idx * maxChar, encoded.length % maxChar);
out.write(newLine.getBytes());
}
}
}
6、查看生成的邮件:
Return-Path: <from@test.com>
Message-ID: <2737550.71240679122296.JavaMail.kinkding@kinkding-d1d01d>
MIME-Version: 1.0
Delivered-To: test@test.com
Received: from localhost ([127.0.0.1])
by kinkding-d1d01d (JAMES SMTP Server 2.3.1) with SMTP ID 4
for <test@test.com>;
Sun, 26 Apr 2009 01:05:20 +0800 (CST)
Date: Sun, 26 Apr 2009 01:05:20 +0800 (CST)
From: from@test.com
To: test@test.com
Subject: =?B?c3VqZWN0INb3zOI=?=
Content-Type: multipart/mixed;boundary="----=_Part_010267414_1240679120062"
------=_Part_010267414_1240679120062
Content-Type: text/plain
Content-Transfer-Encoding: base64
dGV4dCDTyrz+1f3OxA==
------=_Part_010267414_1240679120062
Content-Type: application/octet-stream; name=music.txt
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename=music.txt
MjAwOMTqtsi/4c7STtfaobDX7qGxDQoNCrCuyOfJ2cTqDQoNCg0KKy0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0rDQpNWVNRTDoNCrbLv9qjujMzMDYNClNlcnZlck5hbWU6TXlTUUwN
CnJvb3Qvcm9vdA0KDQorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsNCmRvbWFp
bjoxMjcuMC4wLjENCnNlcnZlciBuYW1lOjEyNy4wLjAuMQ0KZW1haWw6dGVzdEB0ZXN0LmNvbQ0K
DQorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsNClVDZW50ZXI6dWNlbnRlcg0K
ZGlzY3V6OmRpc2N1eg0KaHR0cDovL2xvY2FsaG9zdDo4MDcwL2Rpc2N1ei9pbmRleC5waHANCmh0
dHA6Ly8xOTIuMTY4LjE4LjI6ODA3MC9kaXNjdXovaW5kZXgucGhw
------=_Part_010267414_1240679120062
在FOXMAIL中查看邮件的截图:
7、点击
下载代码