Caused by: com.sun.mail.iap.BadCommandException: A3 BAD invalid command or parameters
一、背景介绍
公司的一个项目根据 javax.mail 统计邮箱里的邮件内容,由于邮件数量很多,如果全量读取收件箱里的邮件的话,会非常耗时,导致时间非常长(根据统计全量读取3000封邮件,耗时平均近7分钟),所以在读取收件箱里的邮件时要根据某些条件进行筛选,这样就很好的解决了这个问题。比如我的项目里,添加了根据时间筛选收件箱里的邮件,效率瞬间都提升上来了。但是我在添加时间范围的时候竟然报错,导致花费了一定的时间,在此做一个记录。
项目主要技术栈:Spring boot (2.0.0.RELEASE) + mybatis-plus (3.1.1) + JDK 1.8 + javax.mail (1.6.1)
关键代码:
Properties props = new Properties(); Session session = Session.getDefaultInstance(props, null); // 邮箱协议 Store store = session.getStore("imap"); // 邮箱主机,用户名和密码 store.connect(mailHost, mailUsername, mailPassword); // 读取收件箱 Folder folder = store.getFolder("INBOX"); folder.open(Folder.READ_ONLY); // 以下为添加根据时间筛选邮件的条件 Calendar calendar = Calendar.getInstance(); // 搜索3天前到今天收到的的所有邮件,根据时间筛选邮件 calendar.add(Calendar.DAY_OF_MONTH, -3); // 创建ReceivedDateTerm对象,ComparisonTerm.GE(大于等于),Date类型的时间 new Date(calendar.getTimeInMillis())----(表示3天前) ReceivedDateTerm term = new ReceivedDateTerm(ComparisonTerm.GE, new Date(calendar.getTimeInMillis())); // 把时间筛选条件添加到收件箱文件夹里,得到3天前到今天的所有邮件 Message[] message = folder.search(term); // Message[] message = folder.getMessages(); 这个是获取收件箱里所有邮件 // todo 进行你的业务
ComparisonTerm类 常用的日期和数字比较中,它使用六个常量 LE(<=)、LT(<)、EQ(=)、NE(!=)、GT(>)、GE(>=)来表示六种不同的比较操作。
如下图是我截取的jdk源码中的类的属性:
二、报错内容
主要报错:Caused by: com.sun.mail.iap.BadCommandException: A3 BAD invalid command or parameters。
详细报错如下:
javax.mail.MessagingException: A3 BAD invalid command or parameters;
nested exception is:
com.sun.mail.iap.BadCommandException: A3 BAD invalid command or parameters
at com.sun.mail.imap.IMAPFolder.search(IMAPFolder.java:1547)
at com.iot.daily.task.MailNoSubmitTask.queryEmailDailyNoSubmitSync(MailNoSubmitTask.java:90)
at com.iot.daily.task.MailNoSubmitTask
����������������������
9403690b.invoke(<generated>) at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:747) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115) at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266) at java.util.concurrent.FutureTask.run(FutureTask.java) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748)Caused by: com.sun.mail.iap.BadCommandException: A3 BAD invalid command or parameters at com.sun.mail.iap.Protocol.handleResult(Protocol.java:296) at com.sun.mail.imap.protocol.IMAPProtocol.issueSearch(IMAPProtocol.java:1471) at com.sun.mail.imap.protocol.IMAPProtocol.search(IMAPProtocol.java:1379) at com.sun.mail.imap.protocol.IMAPProtocol.search(IMAPProtocol.java:1367) at com.sun.mail.imap.IMAPFolder.search(IMAPFolder.java:1527) ... 11 more
三、报错原因
报错的点是 ComparisonTerm.GE 这个比较操作,可能是这个 GE(大于等于)的操作不能和时间比较,如果改成 ComparisonTerm.GT (大于)的操作即可。然后一切正常。
具体的报错原因,还不清楚,希望各位知道的大佬不吝赐教,可在评论区讨论啊,以便帮助更多需要的人。
四、解决方案
把 ComparisonTerm.GE(大于等于) 这个大于等于比较改成 ComparisonTerm.GT (大于)大于比较即可。
即:下面的关键代码。
ReceivedDateTerm term = new ReceivedDateTerm(ComparisonTerm.GE, new Date(calendar.getTimeInMillis()));
改成
ReceivedDateTerm term = new ReceivedDateTerm(ComparisonTerm.GT, new Date(calendar.getTimeInMillis()));
拓展:
SpringBoot javax获取邮件内容,删除邮件、根据时间段筛选邮件,筛选时间段+未读邮件
完结!