javaMail基础:
Session类,它代表与邮件服务器的Session请求(连接),Session和邮件服务器的关系类似于JDBC中的Connection类和数据库系统的关系。每一个基于JavaMail的应用程序至少有一个Session,但可以有任意多个Session。Session对象需要知道用来处理的SMTP服务器和POP服务器。
Message类:这个类封装了和我们信箱中的电子邮件信息一一对应的属性。
Transport类,Store类:用来发送信息的类,它与Store类从某种意义上说是相反。该类用得最多的是send方法。把Message对象设置完毕后,调用send(Message)就可以实现发邮件的功能。Store类实现特定邮件协议的读写监视查找等操作。通过javax.mail.Store类可以访问javax.mail.Folder类。该类常用的方法是:connect()方法来连接邮件服务器,getFolder()来得到待操作的Folder对象。
javaMail收邮件的操作是:1.连接到Pop3邮件服务器2.得到邮件对象数组3.查看指定邮件的信息4.删除邮件。
javamail通过pop3接收到发件人的乱码问题:
邮件发件人的格式为:姓名+<邮件地址>
而有些邮件没姓名,直接是<邮件地址> 。可以把它看成一个字符串,这个字符串先经过编码,然后可以被加密。由于Email的规范,在smtp传输中不可使用中文字符。所以可以使用内置类的MimeUtility方法encodeText将收件人、发件人名字编码即可。编码方式有两种:"B"代表Base64、"Q"代表QP(quoted-printable)方式。
字符串的编码方式:一个字节为8bits,一个字为16bit,编码方式的不同体现在用多少bit表示一个字符。字符串由字符组成,按照不同的编码显示会完全不同。这就是中文乱码问题的所在。Java的String中有getBytes
()
:
使用平台的默认字符集将此 String
编码为 byte 序列,并将结果存储到一个新的 byte 数组中。getBytes
(Charset charset)
使用给定的 charset 将此 String
编码到 byte 序列,并将结果存储到新的 byte 数组。getBytes
(String charsetName)
使用指定的字符集将此 String
编码为 byte 序列,并将结果存储到一个新的 byte 数组中。如果需要加密,就对此byte数组加密。
我从163的pop3的服务器上读取我的邮件,并输出发件人。中文出现了乱码。收件人字符串格式有:utf-8,gbk,gb2312,gb18030。加密形式有"B"代表Base64如:=?gb2312?B?1sfBqtXQxrj=?= <a.jiaji@support150.zhaopin.com>",可以看出,这个字符串的编码格式是:gb2312,而采用了base64加密。Q表QP(quoted-printable)方式:=?utf-8?Q?=E4=B8=AD=E5=8D=8E=E8=8B=B1=E6=89=8D=E7=BD=91?= campusys2010@mychinahr.com可以看出这个字符串采用的编码格式是:utf-8,而采用了quoted-printable加密。
对于没有加密的字符串,直接用rtnStr=new String(str.getBytes("iso-8859-1"));就能正确显示。对于加密的字符串,需要用rtnStr=MimeUtility.decodeText(str);就能解决
我们需要取出邮件地址+发件人名字,发件人名字有些是没有的,这给处理带来了难度,用正则表达式分组可以解决这个问题。也就是说名字可以没有,但是发件人的邮件地址是一定有的。
将得到的收件人字符串通过如下的方法:
通过正则表达式可以将发件人的名字和地址分别取出。
//用匹配=?.*?[B|Q]的加密形式,工作过程是:首先对字符串编码,然后加密:"B"代表Base64、"Q"代表QP(quoted-printable)方式
//对于加密的形式需要进行解密。
private static Pattern p=Pattern.compile("((=//?.*//?[B|Q])(.*))([<](.*)[>]$)",Pattern.CASE_INSENSITIVE);
//对于没有加密的编码,直接用new String(str.getBytes("iso-8859-1")),java中默认的编码是GBK.
private static Pattern p1=Pattern.compile(".*",Pattern.CASE_INSENSITIVE);
private static Matcher m=null;
private static Matcher m1=null;
public static String getChinese(String str){
String rtnStr="";
m=p.matcher(str);
m1=p1.matcher(str);
try {
if (m.find()) {
if (m.group(1)!=null) {
rtnStr=MimeUtility.decodeText(m.group(0));
}else if (m.group(5)!=null){
//rtnStr="为定义的名字";
rtnStr=new String(m.group(0).getBytes("iso-8859-1"));
}
}else if(m1.find()){
//System.out.println(m1.find());
rtnStr=new String(m1.group().getBytes("iso-8859-1"));
}
} catch (Exception e) {
rtnStr=str;
e.printStackTrace();
}
System.out.println(rtnStr);
return rtnStr;
}
得到邮件主题的乱码问题:
邮件主题的乱码不是很复杂,和收件人一样。编码后加密,当然有的也不加密。我们可以对得到的字符串先进行new String(str.getBytes("iso-8859-1")),然后再判断有无? = Q等特殊字符,有的话用MimeUtility.decodeText()就可以解决了。代码如下:
public static String getSubChinese(String str){
String rtnStr="";
try {
rtnStr=new String(str.getBytes("iso-8859-1"));
if (rtnStr.contains("=")) {
rtnStr=MimeUtility.decodeText(str);
}
} catch (UnsupportedEncodingException e) {
rtnStr=str;
e.printStackTrace();
}
System.out.println(rtnStr);
return rtnStr;
}
}