呃,好吧,我只写过三个JavaMail的程序。
都是批量邮件守护程序。决定总结一下,希望非常幸运找到这篇文章的人不会再对这个困惑。
必须明白的基础知识
- STMP协议是如何工作的
协议的标准在这里 http://www.ietf.org/rfc/rfc2821.txt?number=2821
下面是扼要说明(http://www.freesoft.org/CIE/Topics/94.htm ):
Simple Mail Transfer Protocol (SMTP), documented in RFC
821, is Internet’s standard host-to-host mail transport protocol and
traditionally operates over TCP, port 25. In other words, a UNIX user
can type telnet hostname 25 and connect with an SMTP server, if one is
present.
SMTP uses a style of asymmetric request-response protocol popular in
the early 1980s, and still seen occasionally, most often in mail
protocols. The protocol is designed to be equally useful to either a
computer or a human, though not too forgiving of the human. From the
server’s viewpoint, a clear set of commands is provided and
well-documented in the RFC. For the human, all the commands are clearly
terminated by newlines and a HELP command lists all of them. From the
sender’s viewpoint, the command replies always take the form of text
lines, each starting with a three-digit code identifying the result of
the operation, a continuation character to indicate another lines
following, and then arbitrary text information designed to be
informative to a human.
事实上,你可以像使用DOS命令一样发送电子邮件。http://bbs.stcore.com/archiver/tid-8024.htm 当然因为各种原因,你的尝试不可能成功。事实上SMTP工作的时候就是简单的发送命令。取得认证,发送数据。得到反馈。确认退出这么简单。
- SMTP中用于发送的数据
SMTP中发送的数据,遵从Multipurpose Internet Mail Extensions (MIME)标准,呃,我不得不说,这是这个星球上最重要的标准之一。所有的互联网通信基本都是基于这个标准的演化。除了电子邮件,常见的应用还包括HTTP报文等(也就是所有网页了),另外即使在20年后发展的XML,其2进制数据发送仍然实用的MIME中的编码方式。
恩,这里就涉及到邮件附件如何处理的问题。恩,简单地说就是BASE64编码
Table 1: The Base64 Alphabet
Value Encoding Value Encoding Value Encoding Value Encoding
0 A 17 R 34 i 51 z
1 B 18 S 35 j 52 0
2 C 19 T 36 k 53 1
3 D 20 U 37 l 54 2
4 E 21 V 38 m 55 3
5 F 22 W 39 n 56 4
6 G 23 X 40 o 57 5
7 H 24 Y 41 p 58 6
8 I 25 Z 42 q 59 7
9 J 26 a 43 r 60 8
10 K 27 b 44 s 61 9
11 L 28 c 45 t 62 +
12 M 29 d 46 u 63 /
13 N 30 e 47 v
14 O 31 f 48 w (pad) =
15 P 32 g 49 x
16 Q 33 h 50 y
在这种编码中,我们将字符或者二进制编码以6个比特位为一组,替换成相应的字符形式。比如
100110111010001011101001
转换结果就是
100110 -> 38
111010 -> 58
001011 -> 11
101001 -> 41
38 -> m
58 -> 6
11 -> L
41 -> p
m6Lp
于是,我们就可以以文本的方式编码二进制流以及扩展ASCII字符,比如中文字符。
基础知识完毕,下面是FAQ
Java发送电子邮件需要哪些软件包
mail.jar 通常还会需要 activation.jar
下载地址
http://java.sun.com/products/javabeans/jaf/downloads/index.html
https://maven-repository.dev.java.net/nonav/repository/javax.mail/
如何发送邮件
关于:
- 如何发送邮件
- 如何发送带有附件的邮件
- 如何发送中文邮件
- 邮件中文标题乱码怎么办
- 邮件附件乱码怎么办等等问题
请查看以下代码
public static synchronized void sendMail(Properties settings)
throws Exception {
Properties props = new Properties();
props.put("mail.smtp.host", settings.get(StartCore.MAIL_SERVER));
props.put("mail.smtp.user", settings.get(StartCore.USER_NAME));
props.put("mail.smtp.auth", "true");
//SMTP服务器用户验证
Authenticator auth = new SMTPAuthenticator((String) settings
.get(StartCore.USER_NAME), (String) settings
.get(StartCore.PASSWORD));
Session session = Session.getDefaultInstance(props, auth);
if ("true".compareToIgnoreCase((String) settings.get("DEBUG")) == 0) {
session.setDebug(true);
}
//创建消息体
MimeMessage msg = new MimeMessage(session);
//设置发送人邮件
msg.setFrom(new InternetAddress((String) settings
.get(StartCore.USER_MAIL)));
//设置接收人邮件
address = new InternetAddress[] { new InternetAddress(rs
.getString("GRE_mail")) };
msg.setRecipients(Message.RecipientType.TO, address);
//设置主题,中文编码
msg.setSubject(subject, "gbk");
msg.setSentDate(new Date());
String content = "邮件正文";
MimeBodyPart mbp1 = new MimeBodyPart();
mbp1.setText(content, "gbk");
//邮件附件
MimeBodyPart attachFilePart = new MimeBodyPart();
File file = new File("中文附件.txt");
FileDataSource fds = new FileDataSource(file.getName());
attachFilePart.setDataHandler(new DataHandler(fds));
sun.misc.BASE64Encoder enc = new sun.misc.BASE64Encoder();
//解决中文附件名称
attachFilePart.setFileName("=?gbk?B?"
+ enc.encode(file.getName().getBytes("gbk")) + "?=");
Multipart mp = new MimeMultipart();
mp.addBodyPart(mbp1);
mp.addBodyPart(attachFilePart);
msg.setContent(mp);
// send the message
msg.saveChanges();
Transport.send(msg);
}
这是上面用户验证用到的类
class SMTPAuthenticator extends javax.mail.Authenticator {
private String username;
private String password;
/**
* @param username
* @param password
*/
public SMTPAuthenticator(String username, String password) {
this.username = username;
this.password = password;
}
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
}
邮件发送出错
What causes an
“javax.activation.UnsupportedDataTypeException: no object DCH for MIME
type xxx/xxxx javax.mail.MessagingException: IOException while sending
message;” to be sent and how do I fix this? [This happens for known
MIME types like text/htm
事实上这个是邮件发送时验证组件设置不当引起的,这个组件配置方法如下
(http://java.sun.com/j2ee/1.4/docs/api/javax/activation/MailcapCommandMap.html)
The MailcapCommandMap looks in various places in the user’s system
for mailcap file entries. When requests are made to search for commands
in the MailcapCommandMap, it searches mailcap files in the following
order:
1) Programatically added entries to the MailcapCommandMap instance.
2) The file .mailcap in the user’s home directory.
3) The file /lib/mailcap.
4) The file or resources named META-INF/mailcap.
5) The file or resource named META-INF/mailcap.default (usually found only in the activation.jar file).
我选用了第四种方法,在生成的Jar文件中加入了 META-INF/mailcap.
#
# This is a very simple 'mailcap' file
#
image/gif;; x-java-view=com.sun.activation.viewers.ImageViewer
image/jpeg;; x-java-view=com.sun.activation.viewers.ImageViewer
text/*;; x-java-view=com.sun.activation.viewers.TextViewer
text/*;; x-java-edit=com.sun.activation.viewers.TextEditor
text/html;; x-java-content-handler=com.sun.mail.handlers.text_html
text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml
text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain
multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed
message/rfc822;; x-java-content-handler=com.sun.mail.handlers.message_rfc822