您的位置:首页 > 编程语言 > Java开发

spring boot定时任务接收邮件并且存储附件的方法讲解

2019-04-11 09:17 2451 查看

在spring boot中写定时任务很简单,两个注解就可以实现。在启动类中加@EnableScheduling ,然后在你需要定时的方法上加上@Scheduled(cron="0 10 8 * * ?");括号内为cron表达式。如下图:

接收邮件及其判断是否有附件,并且存储附件。

public class TimerTaskServiceImpl implements TimerTaskService {
@Autowired
private ParseTxtServiceImpl parseTxtService;
/**
* 接收邮件
*/
@Override
@Scheduled(cron="0 10 8 * * ?")
public void timerTaskInfo(){
//邮件配置信息
String host=Constants.MAIL_HOST;
String userName=Constants.MAIL_USER_NAME;
String passWord=Constants.MAIL_PASS_WORD;
//邮件配置类
Properties properties=new Properties();
//邮件配置缓存
Session session=Session.getDefaultInstance(properties);
session.setDebug(true);
String fileName=null;
try {
//邮件服务器的类型
Store store = session.getStore("pop3");
//连接邮箱服务器
store.connect(host,userName,passWord);
// 获得用户的邮件帐户
Folder folder=store.getFolder("INBOX");
if (folder == null) {
logger.info("获取邮箱文件信息为空");
}
// 设置对邮件帐户的访问权限可以读写
folder.open(Folder.READ_WRITE);
Calendar calendar=Calendar.getInstance();
calendar.add(Calendar.DATE,-1);
Date mondayDate = calendar.getTime();
SearchTerm comparisonTermLe = new SentDateTerm(ComparisonTerm.GT, mondayDate);
SearchTerm address=new SubjectTerm( "MU Report");
SearchTerm comparisonAndTerm = new AndTerm(address, comparisonTermLe);
Message[] messages = folder.search(comparisonAndTerm);
for(int i = 0 ; i < messages.length ; i++){
MimeMessage msg = (MimeMessage) messages[i];
//判断是否有附件
boolean isContainerAttachment = isContainAttachment(msg);
if (isContainerAttachment) {
//保存附件
fileName=saveAttachment(msg,Constants.STORAGE_FILE);
//保存接收到的邮件并且收件箱删除邮件
msg.setFlag(Flags.Flag.DELETED, true);
}
if(!isContainerAttachment) {
continue;
}
}
folder.close(true);
store.close();
parseTxtService.readTxt(fileName);
}catch (NoSuchProviderException e){
loggerError.error("接收邮箱信息异常:{}",e);
}catch (MessagingException e){
loggerError.error("连接邮箱服务器信息异常:{}",e);
}catch (IOException e){
loggerError.error("接收邮箱信息解析异常:{}",e);
}catch (IllegalStateException e){
loggerError.error("接收邮箱信息为空:{}",e);
}
}
/**
* 判断邮件中是否包含附件
* @return 邮件中存在附件返回true,不存在返回false
* @throws MessagingException
* @throws IOException
*/
public static boolean isContainAttachment(Part part) throws MessagingException, IOException {
boolean flag = false;
if (part.isMimeType(Constants.MULTI_PART)) {
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(Constants.MULTI_PART)) {
flag = isContainAttachment(bodyPart);
} else {
String contentType = bodyPart.getContentType();
if (contentType.indexOf(Constants.APPLICATION_CONTEXT) != -1) {
flag = true;
}
if (contentType.indexOf(Constants.NAME_CONTEXT) != -1) {
flag = true;
}
}
if (flag){
break;
}
}
} else if (part.isMimeType(Constants.MESSAGE_RFC)) {
flag = isContainAttachment((Part)part.getContent());
}
return flag;
}
/**
* 保存附件
* @param part 邮件中多个组合体中的其中一个组合体
* @param destDir 附件保存目录
* @throws UnsupportedEncodingException
* @throws MessagingException
* @throws FileNotFoundException
* @throws IOException
*/
public String saveAttachment(Part part, String destDir) throws UnsupportedEncodingException,
MessagingException, FileNotFoundException, IOException {
String fileName=null;
if (part.isMimeType(Constants.MULTI_PART)) {
Multipart multipart = (Multipart) 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))) {
InputStream is = bodyPart.getInputStream();
saveFile(is, destDir, decodeText(bodyPart.getFileName()));
fileName=decodeText(bodyPart.getFileName());
} else if (bodyPart.isMimeType(Constants.MULTI_PART)) {
saveAttachment(bodyPart,destDir);
} else {
String contentType = bodyPart.getContentType();
if (contentType.indexOf(Constants.NAME_CONTEXT) != -1 || contentType.indexOf
(Constants.APPLICATION_CONTEXT) != -1) {
saveFile(bodyPart.getInputStream(), destDir, decodeText(bodyPart.getFileName()));
fileName=decodeText(bodyPart.getFileName());
}
}
}
} else if (part.isMimeType(Constants.MESSAGE_RFC)) {
saveAttachment((Part) part.getContent(),destDir);
}
return fileName;
}
/**
* 读取输入流中的数据保存至指定目录
* @param is 输入流
* @param fileName 文件名
* @param destDir 文件存储目录
* @throws FileNotFoundException
* @throws IOException
*/
private void saveFile(InputStream is, String destDir, String fileName)
throws FileNotFoundException, IOException {
BufferedInputStream bis = new BufferedInputStream(is);
if(fileName.contains(Constants.TXT_SUFIXX)) {
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(new File(destDir + fileName)));
int len = -1;
while ((len = bis.read()) != -1) {
bos.write(len);
bos.flush();
}
bos.close();
bis.close();
}
}
}

其中查询邮件的条件,你可以自行更改。

接收邮件服务器的配置

可能出现的bug

说说用模板可能会碰到的bug。

怎么回事呢?代码写了,看了好几遍也没错,就是运行就报错,在网上看了别人的代码拿过来还是报错,报错如下:

这个错误大概意思就是我的模板的html中每个标签都要是闭标签,要这种类型的<a></a>,假如是<img xxx>这种标签就会报错。

如下所示,最坑的方法就是修改的,而且以后html的标签都要是一对一对的,坑啊、

后来有找了很多资料,原来发现是这里,themeleaf默认应该是2.xx版本,这个版本解析标签都要是一对一对的,到了3.xx之后,就不需要这么麻烦了!

都是版本问题

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。如果你想了解更多相关内容请查看下面相关链接

您可能感兴趣的文章:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: