原文地址:http://write.blog.csdn.net/postedit
该系统实现类型outlook的功能,能将用户各个邮箱的邮件及时的同步并整理,同时可以通过用户设置的发送邮箱在系统进行发送邮件
系统组件
1. EmailSelecter
2.Sender
一.EmailSelecter组件
主要负责拉取邮件服务器上的邮件列表数据,采用模板模式,EmailSelecter是抽象模板类,抽象了拉取的各个步骤(模板方法)
package com.platform.util.mail;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.mail.Address;
import javax.mail.BodyPart;
import javax.mail.Flags;
import javax.mail.Flags.Flag;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Part;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.URLName;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.mail.util.MimeMessageParser;
import sun.misc.BASE64Decoder;
import com.platform.oa.commange.mail.pojo.NetworkReceiverEmail;
import com.platform.oa.commange.mail.pojo.UserEmailAccount;
import com.platform.util.common.StringUtil;
import com.platform.util.constants.Constants;
import com.sun.mail.pop3.POP3Folder;
import common.Logger;
/**
*
* ========================================================
* 上海建业信息科技有限公司 研发中心
* 日 期:2015 -4- 21 下午3:14:52
* 作 者:姚金权
* 版 本:1.0
* 功能描述:远程邮件查询器
*
* 修订日期 修订人 描述
* 2015-4 -21 姚金权 创建
* ========================================================
*/
public abstract class EmailSelecter {
private static final Logger logger = Logger. getLogger(EmailSelecter.class);
// 定义一个邮箱地址的正则表达式:姓名<邮箱>
private static final Pattern pattern = Pattern. compile("(.+)(<.+@.+..+>)");
/**
*
* @Description: 根据成员变量 构造一个邮件链接
* @param
* @return URLName
* @author 姚金权
* @since 2015- 4-17 下午6:13:36
* @throws
*/
public abstract URLName initURL();
/**
*
* @Description: 初始化配置信息
* @param
* @return void
* @author 姚金权
* @since 2015- 4-17 下午6:14:35
* @throws
*/
public abstract void initProperties(Properties props)throws Exception;
/**
*
* @Description: 链接邮箱
* @param
* @return Store
* @author 姚金权
* @since 2015- 4-17 下午6:12:33
* @throws
*/
public Store conectStore() throws Exception{
// 准备连接服务器的会话信息
Properties props = new Properties();
initProperties(props);
URLName urln = initURL();
Session session = Session. getInstance(props, null);
Store store = session.getStore(urln);
store.connect();
return store;
}
/**
*
* @Description:接收邮件
* @param
* @return InboxSelectResult
* @author 姚金权
* @since 2015- 4-21 下午3:15:19
* @throws
*/
public InboxSelectResult receive(UserEmailAccount account, int selectSize,String rootPath) throws Exception {
Store store = conectStore();
// 获得收件箱
Folder folder = store.getFolder( "INBOX");
// Folder.READ_ONLY:只读权限 Folder.READ_WRITE:可读可写(可以修改邮件的状态)
folder.open(Folder. READ_WRITE); //打开收件箱
InboxSelectResult result = new InboxSelectResult();
result.setCount(folder.getMessageCount());
result.setNewCount(folder.getNewMessageCount());
result.setUnreadCount(folder.getUnreadMessageCount());
result.setDeletedCount(folder.getDeletedMessageCount());
int count = folder.getMessageCount();
if(count < 1){
return result;
}
if(selectSize>count){
selectSize =count;
}
int startIndex = (folder.getMessageCount()-selectSize)+1;
int endIndex = folder.getMessageCount();
// 得到收件箱中的所有邮件,并解析
Message[] messages = folder.getMessages(startIndex, endIndex);
result.setEmails(parseMessage(messages,folder,rootPath));
//释放资源
folder.close( true);
store.close();
return result;
}
/**
*
* @Description:得到包含中文的地址
* @param
* @return String
* @author 姚金权
* @since 2015- 4-21 下午3:15:38
* @throws
*/
public String getChineseAddress(String address){
try{
if(StringUtils.isEmpty(address)){
return "" ;
}
if(address.startsWith( "=?GB")||address.startsWith("=?gb" )){
address=MimeUtility. decodeText(address);
} else{
address=toChinese(address);
}
} catch(Exception e){
e.printStackTrace();
}
return address;
}
/**
*
* @Description:
* @param
* @return String
* @author 姚金权
* @since 2015- 4-21 下午3:16:24
* @throws
*/
public String toChinese(String strvalue){
try{
if(strvalue== null)
return null;
else{
strvalue = new String(strvalue.getBytes("ISO8859_1" ), "UTF-8" );
return strvalue;
}
} catch(Exception e){
return null;
}
}
/**
*
* @Description: 得到base64加密地址
* @param
* @return String
* @author 姚金权
* @since 2015- 4-21 下午3:16:15
* @throws
*/
public String getFromBASE64(String s) {
if (s == null) return null;
BASE64Decoder decoder = new BASE64Decoder();
try {
byte[] b = decoder.decodeBuffer(s);
return new String(b);
} catch (Exception e) {
return null;
}
}
/**
* @throws MessagingException
*
* @Description:判断邮件是否已读
* @param
* @return boolean
* @author 姚金权
* @since 2015- 4-16 下午7:04:20
* @throws
*/
public boolean isReaded(Message message) throws MessagingException{
boolean isRead = false;
Flags flags = message.getFlags();
if(flags.contains(Flags.Flag. SEEN)){
isRead = true;
}
return isRead;
}
/**
* @throws Exception
*
* @Description: 标记远端邮件
* @param
* @return void
* @author 姚金权
* @since 2015- 4-8 下午3:25:48
* @throws
*/
public void markMail(String[] uuids,int startIndex,int endIndex,Flag flag) throws Exception{
Store store = conectStore();
// 获得收件箱
Folder folder = store.getFolder( "INBOX");
// Folder.READ_ONLY:只读权限 Folder.READ_WRITE:可读可写(可以修改邮件的状态)
folder.open(Folder. READ_WRITE); //打开收件箱
Message[] messages = folder.getMessages(startIndex, endIndex);
Map<String,Message> msgMap = new HashMap<String,Message>();
for(Message message:messages){
MimeMessage msg =(MimeMessage)message;
msgMap.put(getUID(folder, msg), message);
}
for(String id:uuids){
Message m = msgMap.get(id);
if(m!=null ){
m.setFlag(flag, true);
}
}
folder.close( true);
store.close();
}
/**
*
* @Description: 删除远端服务器上的邮件
* @param
* @return void
* @author 姚金权
* @since 2015- 4-8 下午3:51:41
* @throws
*/
public void delMail(String[] uuids,int startIndex,int endIndex) throws Exception{
markMail(uuids, startIndex, endIndex, Flag. DELETED);
}
/**
* @throws Exception
*
* @Description: 标记远端邮件为已读
* @param
* @return void
* @author 姚金权
* @since 2015- 4-8 下午3:52:22
* @throws
*/
public void markReaded(String[] uuids,int startIndex,int endIndex) throws Exception{
markMail(uuids, startIndex, endIndex, Flag. SEEN);
}
public void out(MimeMessage msg,Folder folder)throws MessagingException, IOException{
System. out.println("------------------解析第" + msg.getMessageNumber() + "封邮件-------------------- " );
System. out.println("发件人: " + getFrom(msg));
System. out.println("发送时间:" + getSentDate(msg, null));
System. out.println("是否已读:" + isSeen(msg));
System. out.println("邮件优先级:" + getPriority(msg));
System. out.println("是否需要回执:" + isReplySign(msg));
System. out.println("邮件ID:" +getUID(folder,msg));
System. out.println("主题: " + getSubject(msg));
System. out.println("编码:" +msg.getEncoding());
System. out.println("收件人:" + getReceiveAddress(msg));
System. out.println("邮件大小:" + msg.getSize() * 1024 + "kb");
boolean isContainerAttachment = isContainAttachment(msg);
System. out.println("是否包含附件:" + isContainerAttachment);
if (isContainerAttachment) {
// saveAttachment( msg, "c:\\mailtmp \\"+msg.getSubject() + "_"); //保存附件
}
StringBuffer content = new StringBuffer();
getMailTextContent(msg, content);
System. out.println("邮件正文:" + (content.length() > 100 ? content.substring(0,100) + "..." : content));
System. out.println("------------------第" + msg.getMessageNumber() + "封邮件解析结束-------------------- " );
System. out.println();
}
/**
*
* @Description: 得到邮件内容
* @param
* @return String
* @author 姚金权
* @since 2015- 4-3 下午3:09:15
* @throws
*/
public String getContext(MimeMessage msg) throws MessagingException, IOException{
StringBuffer content = new StringBuffer();
getMailTextContent(msg, content);
String s = content.toString();
// s= (s.length() > 100 ? s.substring(0,100) + "..." : s);
return s;
}
/**
* 解析邮件
* @param messages 要解析的邮件列表
*/
public List<NetworkReceiverEmail> parseMessage(Message[] messages,Folder folder,String rootPath) throws MessagingException, IOException {
if (messages == null || messages.length < 1){
throw new MessagingException("未找到要解析的邮件!");
}
List<NetworkReceiverEmail> receiverEmails = new ArrayList<NetworkReceiverEmail>();
for (int i = 0, count = messages.length; i < count; i++) {
NetworkReceiverEmail receiverEmail = new NetworkReceiverEmail();
MimeMessage msg = (MimeMessage) messages[i];
MimeMessageParser parser = null;
try {
parser = new MimeMessageParser(msg).parse();
} catch (Exception e) {
e.printStackTrace();
}
receiverEmail.setSubject(getSubject(msg));
receiverEmail.setFromAddress(getFrom(msg));
receiverEmail.setToAddresses(getReceiveAddress(msg));
receiverEmail.setCcAddresses(getCcAddress(msg));
receiverEmail.setContent(getContext(msg));
receiverEmail.setIsContainerAttachment(isContainAttachment(msg));
receiverEmail.setIsReplySign(isReplySign(msg));
receiverEmail.setEmailKey(getUID(folder,msg));
String htmlContentString = getHtmlContent(parser);
System. out.println("htmlContentString:" +htmlContentString);
receiverEmail.setContentText(htmlContentString);
receiverEmail.setSummary(getSummary(htmlContentString));
receiverEmail.setSendTime(getSentDate(msg));
receiverEmail.setStatus(isReaded(msg)?Constants.EMAIL_STATE_READED:Constants.EMAIL_STATE_NOREADED);
receiverEmail.setPriority(getPriority(msg));
// String attPath = "";
if(isContainAttachment(msg)){
List<com.platform.system.upload.pojo.Attachment> attachments = new ArrayList<com.platform.system.upload.pojo.Attachment>();
saveAttachment(msg, attachments,rootPath);
receiverEmail.setAttachmentList(attachments);
}
receiverEmails.add(receiverEmail);
// out( msg, folder);
}
return receiverEmails;
}
/**
*
* @Description: 得到远程邮件的唯一标示
* @param
* @return String
* @author 姚金权
* @since 2015- 4-21 下午3:18:04
* @throws
*/
public abstract String getUID(Folder folder,MimeMessage msg)throws MessagingException;
/**
*
* @Description:得到邮件html内容
* @param
* @return String
* @author 姚金权
* @since 2015- 4-21 下午3:17:43
* @throws
*/
public String getHtmlContent(MimeMessageParser parser){
if(parser == null){
return null ;
}
return parser.getPlainContent();
}
/**
*
* @Description: 得到摘要信息
* @param
* @return String
* @author 姚金权
* @since 2015- 4-21 下午3:17:17
* @throws
*/
public String getSummary(String content){
if(content == null){
return null ;
}
content = StringUtil. htmlToText(content);
String s= (content.length() > 50 ? content.substring(0,50) : content);
return s;
}
/**
*
* @Description: 解决内容乱码问题
* @param
* @return String
* @author 姚金权
* @since 2015- 4-21 下午3:18:35
* @throws
*/
public String emailDecode(String encode,String text) throws UnsupportedEncodingException{
String subject = text;
if(encode != null && ("quoted-printable" .equals(encode) || "base64".equals(encode))){
subject = MimeUtility. decodeText(text);
}
if(java.nio.charset.Charset.forName("iso-8859-1" ).newEncoder().canEncode(text)){
subject =textDecode(text);
}
return subject;
}
/**
* 获得邮件主题
* @param msg 邮件内容
* @return 解码后的邮件主题
* @throws IOException
*/
public String getSubject(MimeMessage msg) throws MessagingException, IOException {
String encode = msg.getEncoding();
String subject = msg.getSubject();
return emailDecode(encode,subject);
}
public String textDecode(String text){
String result = null;
try {
result = new String(text.getBytes("ISO8859-1" ),"GB2312" );
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
private enum CodecType {
ENCODE, DECODE
}
private String codec(CodecType codecType, String address) {
// 需要对满足匹配条件的邮箱地址进行 UTF-8 编码,否则姓名将出现中文乱码
Matcher addressMatcher = pattern.matcher(address);
if (addressMatcher.find()) {
try {
if (codecType == CodecType.ENCODE) {
address = MimeUtility. encodeText(addressMatcher.group(1), "UTF-8", "B" ) + addressMatcher.group(2);
} else {
address = MimeUtility. decodeText(addressMatcher.group(1)) + addressMatcher.group(2);
}
} catch (UnsupportedEncodingException e) {
logger.error("错误:邮箱地址编解码出错!" , e);
}
}
return address;
}
// 解码邮箱地址
public String decodeAddress(String address) {
return codec(CodecType.DECODE, address);
}
private String[] doParse(Address[] addressList) {
List<String> list = new ArrayList<String>();
if (addressList != null && addressList.length>0 ) {
for (Address address : addressList) {
list.add(decodeAddress(address.toString()));
}
}
return list.toArray(new String[0]);
}
/**
* 获得邮件发件人
* @param msg 邮件内容
* @return 姓名 <Email地址>
* @throws MessagingException
* @throws UnsupportedEncodingException
*/
public String getFrom(MimeMessage msg) throws MessagingException, UnsupportedEncodingException {
Address[] froms = msg.getFrom();
String[] fromPerson = doParse(froms);
if (froms.length < 1)
throw new MessagingException("没有发件人!");
String encode = msg.getEncoding();
String text = fromPerson[0];
return emailDecode(encode, text);
}
/**
* @throws UnsupportedEncodingException
*
* @Description: 得到收件人地址
* @param
* @return String
* @author 姚金权
* @since 2015- 4-3 下午3:03:12
* @throws
*/
public String getReceiveAddress(MimeMessage message) throws MessagingException, UnsupportedEncodingException{
return getAddress(message, Message.RecipientType. TO);
}
/**
* @throws UnsupportedEncodingException
*
* @Description: 得到抄送地址
* @param
* @return String
* @author 姚金权
* @since 2015- 4-3 下午3:04:56
* @throws
*/
public String getCcAddress(MimeMessage message) throws MessagingException, UnsupportedEncodingException{
return getAddress(message,Message.RecipientType. CC);
}
/**
* 根据收件人类型,获取邮件收件人、抄送和密送地址。如果收件人类型为空,则获得所有的收件人
* <p>Message.RecipientType.TO 收件人</p>
* <p>Message.RecipientType.CC 抄送</p>
* <p>Message.RecipientType.BCC 密送</p>
* @param msg 邮件内容
* @param type 收件人类型
* @return 收件人1 <邮件地址1> , 收件人2 <邮件地址2>, ...
* @throws MessagingException
* @throws UnsupportedEncodingException
*/
public String getAddress(MimeMessage msg, Message.RecipientType type) throws MessagingException, UnsupportedEncodingException {
StringBuffer receiveAddress = new StringBuffer();
Address[] addresss = null;
addresss = msg.getRecipients(type);
if (addresss == null || addresss.length < 1){
return receiveAddress.toString();
}
for (Address address : addresss) {
InternetAddress JepEmailInternetAddress = (InternetAddress)address;
receiveAddress.append(JepEmailInternetAddress.toUnicodeString()).append(",");
}
// receiveAddress.deleteCharAt(receiveAddress.length()-1); //删除最后一个逗号
//
String encode = msg.getEncoding();
String addressString = receiveAddress.toString();
return MimeUtility.decodeText(addressString);
System. out.println("encode:" +encode+"text:" +addressString);
addressString = new String(addressString.getBytes("gbk" ),"GB2312" );
return addressString;
}
/**
* 获得邮件发送时间
* @param msg 邮件内容
* @return yyyy年 mm月dd 日 星期X HH:mm
* @throws MessagingException
*/
public String getSentDate(MimeMessage msg, String pattern) throws MessagingException {
Date receivedDate = msg.getSentDate();
if (receivedDate == null)
return "" ;
if (pattern == null || "".equals(pattern))
pattern = "yyyy年MM月dd日 E HH:mm " ;
return new SimpleDateFormat(pattern).format(receivedDate);
}
public Date getSentDate(MimeMessage msg) throws MessagingException {
return msg.getSentDate();
}
/**
* 判断邮件中是否包含附件
* @param msg 邮件内容
* @return 邮件中存在附件返回true,不存在返回false
* @throws MessagingException
* @throws IOException
*/
public boolean isContainAttachment(Part part) throws MessagingException, IOException {
boolean flag = false ;
if (part.isMimeType("multipart/*" )) {
MimeMultipart multipart = (MimeMultipart) part.getContent();
int partCount = multipart.getCount();
for (int i = 0; i < partCount; i++) {
BodyPart bodyPart = multipart.getBodyPart(i);
String disp = bodyPart.getDisposition();
if (disp != null && (disp.equalsIgnoreCase(Part. ATTACHMENT) || disp.equalsIgnoreCase(Part.INLINE ))) {
flag = true;
} else if (bodyPart.isMimeType("multipart/*")) {
flag = isContainAttachment(bodyPart);
} else {
String contentType = bodyPart.getContentType();
if (contentType.indexOf("application" ) != -1) {
flag = true;
}
if (contentType.indexOf("name" ) != -1) {
flag = true;
}
}
if (flag) break ;
}
} else if (part.isMimeType("message/rfc822")) {
flag = isContainAttachment((Part)part.getContent());
}
return flag;
}
/**
* 判断邮件是否已读
* @param msg 邮件内容
* @return 如果邮件已读返回true,否则返回false
* @throws MessagingException
*/
public boolean isSeen(MimeMessage msg) throws MessagingException {
return msg.getFlags().contains(Flags.Flag.SEEN);
}
/**
* 判断邮件是否需要阅读回执
* @param msg 邮件内容
* @return 需要回执返回true,否则返回false
* @throws MessagingException
*/
public boolean isReplySign(MimeMessage msg) throws MessagingException {
boolean replySign = false;
String[] headers = msg.getHeader( "Disposition-Notification-To");
if (headers != null)
replySign = true;
return replySign;
}
/**
* 获得邮件的优先级
* @param msg 邮件内容
* @return 1(High):紧急 3:普通(Normal) 5:低(Low)
* @throws MessagingException
*/
public int getPriority(MimeMessage msg) throws MessagingException {
int priority = 0;
String[] headers = msg.getHeader( "X-Priority");
if (headers != null) {
String headerPriority = headers[0];
if (headerPriority.indexOf("1" ) != -1 || headerPriority.indexOf("High" ) != -1)
priority = 1;
else if (headerPriority.indexOf("5") != -1 || headerPriority.indexOf("Low" ) != -1)
priority = 5;
else
priority = 3;
}
return priority;
}
public String getMailContent2(Part part) throws Exception{
String contenttype=part.getContentType();
StringBuffer bodytext = new StringBuffer();
int nameindex=contenttype.indexOf("name" );
boolean conname=false ;
if(nameindex!=-1)conname=true;
if(part.isMimeType("text/plain" )&&!conname){
bodytext.append((String)part.getContent());
} else if (part.isMimeType("text/html")&&!conname){
bodytext.append((String)part.getContent());
}
else if (part.isMimeType("multipart/*")){
Multipart multipart=(Multipart)part.getContent();
int counts=multipart.getCount();
for(int i=0;i<counts;i++){
getMailContent2(multipart.getBodyPart(i));
}
} else if (part.isMimeType("message/rfc822")){
getMailContent2((Part)part.getContent());
}
else{}
return bodytext.toString();
}
/**
* 获得邮件文本内容
* @param part 邮件体
* @param content 存储邮件文本内容的字符串
* @throws MessagingException
* @throws IOException
*/
public void getMailTextContent(Part part, StringBuffer content) throws MessagingException, IOException {
//如果是文本类型的附件,通过getContent方法可以取到文本内容,但这不是我们需要的结果,所以在这里要做判断
boolean isContainTextAttach = part.getContentType().indexOf("name") > 0;
if (part.isMimeType("text/*" ) && !isContainTextAttach) {
content.append(part.getContent().toString());
} else if (part.isMimeType("message/rfc822")) {
getMailTextContent((Part)part.getContent(),content);
} 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,content);
}
}
}
/**
* 保存附件
* @param part 邮件中多个组合体中的其中一个组合体
* @param destDir 附件保存目录
* @throws UnsupportedEncodingException
* @throws MessagingException
* @throws FileNotFoundException
* @throws IOException
*/
public void saveAttachment(Part part, List<com.platform.system.upload.pojo.Attachment> attachments,String rootPath) throws UnsupportedEncodingException, MessagingException,
FileNotFoundException, IOException {
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);
String contentType = bodyPart.getContentType();
//某一个邮件体也有可能是由多个邮件体组成的复杂体
String disp = bodyPart.getDisposition();
if (disp != null && (disp.equalsIgnoreCase(Part. ATTACHMENT) || disp.equalsIgnoreCase(Part.INLINE ))) {
InputStream is = bodyPart.getInputStream();
String fileName = bodyPart.getFileName();
fileName = decodeText(fileName);
String savefileName = genFileName(fileName);
String filePath = getAttachmentPath(fileName);
String path = rootPath+getAttachmentPath(fileName);
saveFile(is, path,savefileName);
com.platform.system.upload.pojo.Attachment attachment = new com.platform.system.upload.pojo.Attachment();
attachment.setPath(filePath+ "\\"+savefileName);
attachment.setFileName(fileName);
attachments.add(attachment);
} else if (bodyPart.isMimeType("multipart/*")) {
saveAttachment(bodyPart,attachments,rootPath);
} else {
if (contentType.indexOf("name" ) != -1 || contentType.indexOf("application" ) != -1) {
String fileName = decodeText(bodyPart.getFileName());
String savefileName = genFileName(fileName);
String path = rootPath+getAttachmentPath(fileName)+"\\" +savefileName;
saveFile(bodyPart.getInputStream(), path,savefileName);
com.platform.system.upload.pojo.Attachment attachment = new com.platform.system.upload.pojo.Attachment();
attachment.setPath(path);
attachment.setFileName(fileName);
attachments.add(attachment);
}
}
}
} else if (part.isMimeType("message/rfc822")) {
saveAttachment((Part) part.getContent(),attachments,rootPath);
}
}
/**
*
* @Description:得到保存附件的地址
* @param
* @return String
* @author 姚金权
* @since 2015- 4-21 下午3:19:26
* @throws
*/
public String getAttachmentPath(String fileName){
Date nowTime = new Date();
String year = StringUtil. DateToString(nowTime,"yyyy");
String year_month=StringUtil. DateToString(nowTime, "yyyy-MM");
String year_month_day=StringUtil. DateToString(nowTime, "yyyy-MM-dd");
String autoCreatedDateDir = "\\"+year+"\\" +year_month+"\\" +year_month_day;
String mailDir = "mail"+autoCreatedDateDir;
String mailPath = mailDir;
return mailPath;
}
/**
*
* @Description:得到附件的唯一名称
* @param
* @return String
* @author 姚金权
* @since 2015- 4-21 下午3:19:50
* @throws
*/
public String genFileName(String oldFileName){
String fileSaveName = StringUtils. join(new String[] { java.util.UUID.randomUUID().toString(), ".",FilenameUtils.getExtension(oldFileName)});
return fileSaveName;
}
/**
* 读取输入流中的数据保存至指定目录
* @param is 输入流
* @param fileName 文件名
* @param destDir 文件存储目录
* @throws FileNotFoundException
* @throws IOException
*/
private void saveFile(InputStream is, String path,String saveFileName)
throws FileNotFoundException, IOException {
File saveFile = new File(path);
if (!saveFile.exists()){
saveFile.mkdirs();
}
BufferedInputStream bis = new BufferedInputStream(is);
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(path+"\\" +saveFileName));
int len = -1;
while ((len = bis.read()) != -1) {
bos.write(len);
bos.flush();
}
bos.close();
bis.close();
}
/**
* 文本解码
* @param encodeText 解码MimeUtility.encodeText(String text)方法编码后的文本
* @return 解码后的文本
* @throws UnsupportedEncodingException
*/
public String decodeText(String encodeText) throws UnsupportedEncodingException {
if (encodeText == null || "".equals(encodeText)) {
return "" ;
} else {
return MimeUtility.decodeText(encodeText);
}
}
}
实现了POP3协议允许电子邮件客户端下载服务器上的邮件,但是在客户端的操作(如移动邮件、标记已读等),不会反馈到服务器上,比如通过客户端收取了邮箱中的3封邮件并移动到其他文件夹,邮箱服务器上的这些邮件是没有同时被移动的 。而IMAP提供webmail 与电子邮件客户端之间的双向通信,客户端的操作都会反馈到服务器上,对邮件进行的操作,服务器上的邮件也会做相应的动作。
为了让系统适应新老邮件服务器(两种不同的协议 pop3和imap) 在EmailSelecter 下实现两个具体组件
a.IMAPEmailSelecter
b.POP3EmailSelecter
package com.platform.util.mail;
import java.util.Properties;
import javax.mail.Folder;
import javax.mail.MessagingException;
import javax.mail.URLName;
import javax.mail.internet.MimeMessage;
import com.sun.mail.imap.IMAPFolder;
/**
*
* ========================================================
* 上海建业信息科技有限公司 研发中心
* 日 期:2015 -4- 21 下午3:21:45
* 作 者:姚金权
* 版 本:1.0
* 功能描述:基于 imap协议的邮件查询器
*
* 修订日期 修订人 描述
* 2015-4 -21 姚金权 创建
* ========================================================
*/
public class IMAPEmailSelecter extends EmailSelecter{
String port;
String host;
String username;
String password;
String protocol;
public IMAPEmailSelecter(String host,String port,String protocol,String username,String password){
this.port = port;
this.host = host;
this.protocol = protocol;
this.username = username;
this.password = password;
}
/**
*
* @Description: 初始化配置信息
* @param
* @return URLName
* @author 姚金权
* @since 2015- 4-17 下午6:13:36
* @throws
*/
public void initProperties(Properties props) throws Exception{
String pop3Port = "110";
if(port != null){
pop3Port = port;
}
props.setProperty( "mail.store.protocol", "imap" ); // 协议
props.setProperty( "mail.imap.host", host ); // pop3服务器
props.setProperty( "mail.imap.port", "143" );
}
/**
*
* @Description: 初始化请求链接
* @param
* @return URLName
* @author 姚金权
* @since 2015- 4-17 下午6:13:36
* @throws
*/
@Override
public URLName initURL() {
return new URLName(protocol, host, Integer.parseInt(port ), null, username, password );
}
/**
*
* @Description: 得到邮件的唯一标示
* @param
* @return URLName
* @author 姚金权
* @since 2015- 4-17 下午6:13:36
* @throws
*/
@Override
public String getUID(Folder folder, MimeMessage msg)
throws MessagingException {
IMAPFolder imapFolder = (IMAPFolder)folder;
String uid = String. valueOf(imapFolder.getUID(msg));
return uid;
}
}
package com.platform.util.mail;
import java.security.Security;
import java.util.Properties;
import javax.mail.Folder;
import javax.mail.MessagingException;
import javax.mail.URLName;
import javax.mail.internet.MimeMessage;
import com.platform.oa.commange.mail.pojo.EmailHost;
import com.platform.oa.commange.mail.pojo.UserEmailAccount ;
import com.sun.mail.pop3.POP3Folder;
/**
*
* ========================================================
* 上海建业信息科技有限公司 研发中心
* 日 期:2015 -4- 21 下午3:30:05
* 作 者:姚金权
* 版 本:1.0
* 功能描述:基于pop3协议的邮件查询器
*
* 修订日期 修订人 描述
* 2015-4 -21 姚金权 创建
* ========================================================
*/
public class POP3EmailSelecter extends EmailSelecter {
String port;
String host;
String username;
String password;
String protocol;
public POP3EmailSelecter(String host,String port,String protocol,String username,String password){
this.port = port;
this.host = host;
this.protocol = protocol;
this.username = username;
this.password = password;
}
/**
* @throws Exception
*
* @Description: 初始化邮件配置信息
* @param
* @return void
* @author 姚金权
* @since 2015- 4-3 下午1:48:45
* @throws
*/
public void initProperties(Properties props) throws Exception{
props.setProperty( "mail.store.protocol", "pop3" ); // 协议
props.setProperty( "mail.pop3.port", port ); // 端口
props.setProperty( "mail.pop3.host", host ); // pop3服务器
props.setProperty( "mail.pop3.disabletop", "true" );
props.setProperty( "mail.mime.address.strict", "false" );
}
@Override
public String getUID(Folder folder, MimeMessage msg) throws MessagingException {
POP3Folder pop3Folder = (POP3Folder)folder;
return pop3Folder.getUID(msg);
}
@Override
public URLName initURL() {
return new URLName(protocol, host, Integer.parseInt(port ), null, username, password );
}
}
package com.platform.util.mail;
import java.util.List;
import javax.mail.Message;
import com.platform.oa.commange.mail.pojo.NetworkReceiverEmail;
/**
*
* ========================================================
* 上海建业信息科技有限公司 研发中心
* 日 期:2015-4-3 下午1:43:40
* 作 者:姚金权
* 版 本:1.0
* 功能描述:查询的收件箱结果
*
* 修订日期 修订人 描述
* 2015-4-3 姚金权 创建
* ========================================================
*/
public class InboxSelectResult {
//未读邮件数
private Integer unreadCount;
//已经删除邮件数
private Integer deletedCount;
//新邮件数
private Integer newCount;
//邮件总数
private Integer count;
//查询到的邮件
private List<NetworkReceiverEmail> emails;
public Integer getUnreadCount() {
return unreadCount;
}
public void setUnreadCount(Integer unreadCount) {
this.unreadCount = unreadCount;
}
public Integer getDeletedCount() {
return deletedCount;
}
public void setDeletedCount(Integer deletedCount) {
this.deletedCount = deletedCount;
}
public Integer getNewCount() {
return newCount;
}
public void setNewCount(Integer newCount) {
this.newCount = newCount;
}
public Integer getCount() {
return count;
}
public void setCount(Integer count) {
this.count = count;
}
public List<NetworkReceiverEmail> getEmails() {
return emails;
}
public void setEmails(List<NetworkReceiverEmail> emails) {
this.emails = emails;
}
public String toString(){
return "邮件总数:"+this.count+" 新邮件:"+this.newCount+" 未读邮件:"+this.unreadCount+" 已删除邮件:"+this.deletedCount;
}
}
如果用户勾选SLL安全选项
package com.platform.util.mail;
import java.security.Security;
import java.util.Properties;
public class IMAPSLLEmailSelecter extends IMAPEmailSelecter {
public IMAPSLLEmailSelecter(String host, String port, String protocol,
String username, String password) {
super(host, port, protocol, username, password);
// TODO Auto-generated constructor stub
}
public void initProperties(Properties props) throws Exception{
String imapPort = "993";
if(port != null){
imapPort = port;
}
final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory" ;
Security. addProvider(new com.sun.net.ssl.internal.ssl.Provider());
props.setProperty( "mail.imap.socketFactory.class" , SSL_FACTORY);
props.setProperty( "mail.imap.socketFactory.fallback" , "false" );
props.setProperty( "mail.imap.port", imapPort);
props.setProperty( "mail.imap.socketFactory.port" , imapPort);
}
}
package com.platform.util.mail;
import java.security.Security;
import java.util.Properties;
public class POP3SLLEmailSelecter extends POP3EmailSelecter {
public POP3SLLEmailSelecter(String host, String port, String protocol,
String username, String password) {
super(host, port, protocol, username, password);
}
/**
* @throws Exception
*
* @Description: 初始化邮件配置信息
* @param
* @return void
* @author 姚金权
* @since 2015-4-3 下午1:48:45
* @throws
*/
public void initProperties(Properties props) throws Exception{
final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
props.setProperty("mail.pop3.socketFactory.class", SSL_FACTORY);
props.setProperty("mail.pop3.socketFactory.fallback", "false");
props.setProperty("mail.pop3.port", port);
props.setProperty("mail.pop3.socketFactory.port", port);
}
}
----
spring mvc+tomcat源码分析视频(链接复制在浏览器打开)
https://study.163.com/course/courseMain.htm?share=2&shareId=480000001919582&courseId=1209399899&_trace_c_p_k2_=6d81bc445e9c462ab8d6345e40f6b0bf