1.邮件
1.1 邮件组成部分
如果是新邮件就获取,并解析它;邮件是由邮件头和邮件体组成,在邮件头中主要包含了收件人、发件人、主题等等基础信息。而邮件体中就包括了邮件的正文和附件等内容信息。下图就是pop3协议下,邮件的大致内容。
1.2 发送邮件(带附件、正文带图片)
QQ邮箱为例:需要QQ账号和QQ登录第三方客户端时,密码框的“授权码”(相当于密码)
授权码如下获取:
代码如下:
public class JavaMailboxAttachment {
private MimeMessage message;
private Session session;
private String mailHost = "";
private String mailAuth = "";
private String mailPort = "";
private String sender_username = "";
private String sender_password = "";
//定义一个Properties 用于存放信息
private Properties properties = new Properties();
//-------------------------------发信箱---------------------------------------------
public JavaMailboxAttachment(String email_type) {
try {
properties.put("mail.smtp.host","https://www.wendangku.net/doc/f516789748.html,"); //发送邮件服务器
//端口号,QQ邮箱给出了两个端口,但是另一个我一直使用不了,所以就给出这一个587
properties.put("mail.smtp.port", "587"); //发送邮件端口号
properties.put("mail.smtp.auth", "true");
// 此处填写你的账号
properties.put("https://www.wendangku.net/doc/f516789748.html,er", "xxxxxxxxx@https://www.wendangku.net/doc/f516789748.html,");
// 此处的密码就是前面说的16位STMP授权码
properties.put("mail.password", "xxxxxxxxxxxxxxxx");
this.mailHost = properties.getProperty("mail.smtp.host");
this.mailAuth = properties.getProperty("mail.smtp.auth");
this.mailPort = properties.getProperty("mail.smtp.port");
this.sender_username = properties.getProperty("https://www.wendangku.net/doc/f516789748.html,er");
this.sender_password = properties.getProperty("mail.password");
} catch (Exception e) {
e.printStackTrace();
}
// 构建授权信息,用于进行SMTP进行身份验证
Authenticator authenticator = new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
// 用户名、密码
String userName = properties.getProperty("https://www.wendangku.net/doc/f516789748.html,er");
String password = properties.getProperty("mail.password");
return new PasswordAuthentication(userName, password);
}
};
session = Session.getInstance(properties,authenticator); //用户验证
message = new MimeMessage(session); //将验证成功的session信息,创建一个message 对象。
}
/**
* 发送邮件
* @param subject
* 邮件主题
* @param sendHtml
* 邮件内容
* @param receiveUser
* 收件人地址
* @param file
* 附件
*/
public int doSendHtmlEmail(String subject, String sendHtml, String receiveUser, Vector file) {
try {
// 发件人
InternetAddress from = new InternetAddress(sender_username);
message.setFrom(from);
// 收件人
InternetAddress to = new InternetAddress(receiveUser);
message.setRecipient(Message.RecipientType.TO, to);
// 邮件主题
message.setSubject(subject);
// 向multipart对象中添加邮件的各个部分内容,包括文本内容带图片和附件
BodyPart contentPart = new MimeBodyPart();
Multipart multipart = new MimeMultipart("related"); //用于来关联文本内容中图片。
// 添加邮件正文
String imgaeString=Qh_method.randNumID("qunhong_"); //生成一个随机数,大家可以自己写
multipart.addBodyPart(contentPart);
//利用正则找出图片中的src改成cid
final Pattern imgRegExp = https://www.wendangku.net/doc/f516789748.html,pile( "]+src\\s*=\\s*['\"]([^'\"]+)['\"][^>]*>" );
Map
final Matcher matcher = imgRegExp.matcher( sendHtml );
int i = 0;
while ( matcher.find() ) {
String src = matcher.group();
if ( sendHtml.indexOf( src ) != -1 ) {
String srcToken = "src=\"";
int x = src.indexOf( srcToken );
int y = src.indexOf( "\"", x + srcToken.length() );
String srcText = src.substring( x + srcToken.length(), y );
String Sub = srcText.substring(srcText.indexOf("."),srcText.length());
String cid = imgaeString + i;
String newSrc = src.replace( srcText, "cid:" + cid +Sub);
inlineImage.put( cid, srcText.split( "," )[0] );
sendHtml = sendHtml.replace( src, newSrc );
i++;
}
}
//这里说明一下为什么要将正文里的图片转为cid,个人理解:附件和正文里的图片都归于附件传输,设置cid用于识别附件是否为正文底下图片。
//修改后正文内容放置contentPart
contentPart.setContent(sendHtml, "text/html;charset=UTF-8");
//获取项目路径,来获得正文底下的图片,上传至服务器。
String path = this.getClass().getProtectionDomain().getCodeSource().getLocation().getFile();
int indexOf = path.indexOf("xxxxxxxxx");
path=path.substring(0,indexOf);
for (int j = 0; j < inlineImage.size(); j++) {
MimeBodyPart jpgBody = new MimeBodyPart();
FileDataSource fds = new FileDataSource(path+inlineImage.get(imgaeString+j));
jpgBody.setDataHandler(new DataHandler(fds));
jpgBody.setContentID(imgaeString+j); //必须与cid一样
String Sub = inlineImage.get(imgaeString+j).substring(inlineImage.get(imgaeString+j).indexOf("."),inlineImage. get(imgaeString+j).length());
jpgBody.setFileName(MimeUtility.encodeWord(imgaeString+j+Sub));
multipart.addBodyPart(jpgBody);
}
// 添加附件的内容
if(!file.isEmpty()){//有附件
Enumeration efile=file.elements();
while(efile.hasMoreElements()){
BodyPart attachmentBodyPart = new MimeBodyPart();
String file_name=efile.nextElement().toString(); //选择出每一个附件名
FileDataSource fds=new FileDataSource(file_name); //得到数据源
attachmentBodyPart.setDataHandler(new DataHandler(fds)); //得到附件本身并至入BodyPart
attachmentBodyPart.setFileName(MimeUtility.encodeWord(fds.getName())); //得到文件名同样至入BodyPart
multipart.addBodyPart(attachmentBodyPart);
}
file.removeAllElements();
}
// 将multipart对象放到message中
message.setContent(multipart);
// 保存邮件
long start=System.currentTimeMillis();
// 发送
Transport.send(message);
System.out.println("send success!");
long end=System.currentTimeMillis();
System.out.println("发送邮箱使用了"+(end-start)/1000);
} catch (Exception e) {
e.printStackTrace();
return 0;
} finally {
}
return 1;
}
public static void main(String[] args) throws Exception {
Vector file_Vector = new Vector(); //存放文件的集合
file_Vector.add("D://11.txt");
file_Vector.add("D://22.txt");
JavaMailboxAttachment se = new JavaMailboxAttachment(email_type);
zt=se.doSendHtmlEmail(Mailbox_title,Text,receive_account,file);
}
}
1.3 接收邮件(带附件、正文带图片)
public class JavaMailboxAttachment {
private MimeMessage message;
private Session session;
private String mailHost = "";
private String mailAuth = "";
private String mailPort = "";
private String sender_username = "";
private String sender_password = "";
private Properties properties = new Properties();
private static String strSQL="";
private String file_unique="";
private String file_mc="";
private HashMap
private MimeMessage mimeMessage = null;
public JavaMailboxAttachment(MimeMessage mimeMessage) {
this.mimeMessage = mimeMessage;
}
//-------------------------------收信箱---------------------------------------------
public JavaMailboxAttachment(String user_number,String user_password,String receive_name,String receive_account) {
try {
// 准备连接服务器的会话信息//不需要变
long start=System.currentTimeMillis();
Properties props = new Properties();
props.setProperty("mail.store.protocol", "imap");
props.setProperty("mail.imap.host", "https://www.wendangku.net/doc/f516789748.html,");
props.setProperty("mail.imap.port", "143");
/** QQ邮箱需要建立ssl连接*/
props.setProperty("mail.imap.socketFactory.class", "https://www.wendangku.net/doc/f516789748.html,.ssl.SSLSocketFactory");
props.setProperty("mail.imap.socketFactory.fallback", "false");
props.setProperty("mail.imap.starttls.enable","true");
props.setProperty("mail.imap.socketFactory.port", "993");
// 创建Session实例对象
Session session = Session.getInstance(props);
URLName urln = new URLName("imap", "https://www.wendangku.net/doc/f516789748.html,", 143, null,"xxxxxxxxx@https://www.wendangku.net/doc/f516789748.html,","xxxxxxxxxxxxxx");
// 创建IMAP协议的Store对象
Store store = session.getStore(urln);
store.connect();
// 获得收件箱
Folder folder = store.getFolder("INBOX");
// 以读写模式打开收件箱
folder.open(Folder.READ_WRITE);
Message[] messages_UnRead = folder.getMessages(folder.getMessageCount()-folder.getUnreadMessageCount()+1,folder.getMes sageCount()) ; //获取未读邮件的个数
if(messages_UnRead.length!=0){
Message[] messages= folder.getMessages();
for (Message message : messages) {
JavaMailboxAttachment pmm = new JavaMailboxAttachment((MimeMessage) message);
if(!pmm.isNew()){ //True 表示已读
HashMap map=new HashMap();
//每次进来将其设置为空
isMapImage.clear();
file_unique="";
file_mc="";
map.put("receive_account", receive_account);
map.put("receive_name", receive_name);
//保存所有附件(包括正文的图片)
map=saveAttachMent((Part)message,map);
map.put("file_unique", file_unique);
map.put("file_mc", file_mc);
//获取地址,发件人
map=getMailContent(message,map);
//获取正文
map=getMailTextContent(message,map);
//标记为已读
message.setFlag(Flags.Flag.SEEN, true);
int zt = 0;
}
}
}
long end=System.currentTimeMillis();
System.out.println("发送邮箱使用了"+(end-start)/1000);
// 解析邮件
// 关闭资源
folder.close(false);
store.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 将附件和正文图片保存置本地
*/
public HashMap saveAttachMent(Part part,HashMap map) throws Exception {
String ids="";
String fileName = "";
if (part.isMimeType("multipart/*")) {
Multipart mp = (Multipart) part.getContent();
for (int i = 0; i < mp.getCount(); i++) {
BodyPart mpart = mp.getBodyPart(i);
String disposition = mpart.getDisposition();
//判断是否是附件
if ((disposition != null) && ((disposition.equals(Part.ATTACHMENT)) || (disposition.equals(Part.INLINE)))) {
fileName = mpart.getFileName();
if (fileName.toLowerCase().indexOf("gb2312") != -1||fileName.toLowerCase().indexOf("utf") != -1){
fileName = MimeUtility.decodeText(fileName);
}
if(fileName.indexOf("=?")>=0&&fileName.indexOf("?=")>=0){
fileName=fileName.substring(fileName.indexOf("=?"),https://www.wendangku.net/doc/f516789748.html,stIndexOf("?=")+2);
fileName=MimeUtility.decodeText(fileName);
}
String isCid=""; //区别附件与正文图片地方
try {
if(!mpart.getHeader("Content-ID")[0].equals("")){
isCid=mpart.getHeader("Content-ID")[0].replace("<", "").replace(">", "");
}
} catch (Exception e) {
}
String path =GetPath();
if(fileName.indexOf("qunhong_")!=-1){
saveFile(fileName, mpart.getInputStream());
}else if(!isCid.equals("")){
String
subString=fileName.substring(fileName.indexOf("."), fileName.length());
saveFile(fileName, mpart.getInputStream());
renameFile(path+fileName,path+isCid+subString);
isMapImage.put(isCid,isCid+subString);
}else{
String img_name=Qh_method.randNumID("img");
String
subString=fileName.substring(fileName.indexOf("."), fileName.length());
//更改文件名
saveFile(fileName, mpart.getInputStream()); renameFile(path+fileName,path+img_name+subString);
file_unique+="/File_all/record_mail/"+img_name+subString+",";
file_mc+=fileName+",";
}
} else if (mpart.isMimeType("multipart/*")) {
saveAttachMent(mpart,map);
} else {
//QQ正文图片获取处//这里QQ的正文图片比较特殊需要这里获取,下载至本地
fileName = mpart.getFileName();
if ((fileName != null)) {
if(fileName.indexOf("=?")>=0&&fileName.indexOf("?=")>=0){
fileName=fileName.substring(fileName.indexOf("=?"),https://www.wendangku.net/doc/f516789748.html,stIndexOf("?=")+2);
fileName=MimeUtility.decodeText(fileName);
}
saveFile(fileName, mpart.getInputStream());
}
}
}
} else if (part.isMimeType("message/rfc822")) {
saveAttachMent((Part) part.getContent(),map);
}
return map;
}
private void saveFile(String fileName, InputStream is) {
try {
String path = GetPath();
FileOutputStream fos = new FileOutputStream(path+fileName);
int len = 0;
byte[] bys = new byte[1024];
while ((len = is.read(bys)) != -1) {
fos.write(bys,0,len);
}
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private String GetPath() { //获取绝对路径
String path = this.getClass().getProtectionDomain().getCodeSource().getLocation().getFile();
int indexOf = path.indexOf("WEB-INF");
path=path.substring(0,indexOf)+"File_all/record_mail/";
return path;
}
/**
* 解析综合数据
* @param part
* @param map2
* @throws Exception
*/
private HashMap getMailContent(Message msg,HashMap map) throws Exception{
Address[] froms = msg.getFrom();
if(froms != null) {
//System.out.println("发件人信息:" + froms[0]);
InternetAddress addr = (InternetAddress)froms[0];
map.put("sent_account", addr.getAddress());
map.put("sent_name", addr.getPersonal());
}
map.put("mailbox_title",msg.getSubject());
/* Multipart o = (Multipart) msg.getContent(); */
return map;
}
/**
* 获得邮件文本内容
* @param part 邮件体
* @param map 存储邮件文本内容的字符串
* @return
* @throws MessagingException
* @throws IOException
*/
public HashMap getMailTextContent(Part part, HashMap map) throws MessagingException, IOException {
//如果是文本类型的附件,通过getContent方法可以取到文本内容,但这不是我们需要的结果,所以在这里要做判断
boolean isContainTextAttach = part.getContentType().indexOf("name") > 0;
if (part.isMimeType("text/*") && !isContainTextAttach) {
//循环Map存在则替换//需要将正文中cid置换成src路径
String path = GetPathRelation();
System.out.println(part.getContent().toString());
String pictureContent=part.getContent().toString().replace("cid:",path);
Iterator ite=isMapImage.entrySet().iterator();
while(ite.hasNext()){
Entry string=(Entry)ite.next();
System.out.println(string.getKey().toString());
System.out.println(string.getValue().toString());
pictureContent=pictureContent.replace(string.getKey().toString(),string.getValue().toString());
}
System.out.println(pictureContent);
map.put("text", pictureContent);
} else if (part.isMimeType("message/rfc822")) {
getMailTextContent((Part)part.getContent(),map);
} else if (part.isMimeType("multipart/*")) {
Multipart multipart = (Multipart) part.getContent();
int partCount = multipart.getCount();
for (int i = 0; i < partCount; i++) {
BodyPart bodyPart = multipart.getBodyPart(i);
getMailTextContent(bodyPart,map);
}
}
return map;
}
private String GetPathRelation() { //相对路径
String path = this.getClass().getProtectionDomain().getCodeSource().getLocation().getFile();
int indexOf = path.indexOf("WEB-INF");
path=path.substring(0,indexOf)+"File_all/record_mail/";
indexOf = path.indexOf("webapps");
path=path.substring(indexOf,path.length());
path=path.replace("webapps", "");
return path;
}
public void renameFile(String file, String toFile) { //重命名文件夹
File toBeRenamed = new File(file);
//检查要重命名的文件是否存在,是否是文件
if (!toBeRenamed.exists() || toBeRenamed.isDirectory()) {
System.out.println("File does not exist: " + file);
return;
}
File newFile = new File(toFile);
//修改文件名
if (toBeRenamed.renameTo(newFile)) {
System.out.println("File has been renamed.");
} else {
System.out.println("Error renmaing file");
}
}
public boolean isNew() throws MessagingException { //判断是否为未读文件
boolean isnew = false;
Flags flags = ((Message) mimeMessage).getFlags();
Flags.Flag[] flag = flags.getSystemFlags();
for (int i = 0; i < flag.length; i++) {
if (flag[i] == Flags.Flag.SEEN) {
isnew = true;
break;
}
}
return isnew;
}
}
谢谢您用宝贵的时候看完本人编写的文档,若有不足之处或是想要了解的地方,可以加本人QQ:308205428进行交流。本人不才,只是想让自己成果分享给大家!!!/笑脸/笑脸/笑脸/笑脸/笑脸