我花了一天的时间来寻找这种异常的一些解释。我尝试以编程方式配置ImapMailReceiver和ImapIdleChannelAdapter。
在 Pro Spring Integration 书中,我没有找到有关此问题的任何教程,只是一些小信息。
public void loadMessages() { ImapIdleChannelAdapter imapIdleChannelAdapter = null; ImapMailReceiver imapMailReceiver = null; try { imapMailReceiver = new ImapMailReceiver("imaps://" + URLEncoder.encode(USERNAME, "UTF-8") + ":" + PASSWORD + "@imap.gmail.com:993/INBOX"); imapMailReceiver.setShouldMarkMessagesAsRead(true); imapMailReceiver.setShouldDeleteMessages(false); Properties javaMailProperties = new Properties(); javaMailProperties.put(MAIL_IMAP_SOCKET_FACTORY_CLASS, environment.getProperty(MAIL_IMAP_SOCKET_FACTORY_CLASS, SOCKET_FACTORY_CLASS)); javaMailProperties.put(MAIL_IMAP_SOCKET_FACTORY_FALLBACK, environment.getProperty(MAIL_IMAP_SOCKET_FACTORY_FALLBACK, Boolean.class, SOCKET_FACTORY_FALLBACK)); javaMailProperties.put(MAIL_STORE_PROTOCOL, environment.getProperty(MAIL_STORE_PROTOCOL, INBOX_MAIL_PROTOCOL)); javaMailProperties.put(MAIL_DEBUG, environment.getProperty(MAIL_DEBUG, Boolean.class, MAIL_DEBUG_VAL)); imapMailReceiver.setJavaMailProperties(javaMailProperties); imapMailReceiver.setJavaMailAuthenticator(new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(USERNAME, PASSWORD); } }); ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler(); threadPoolTaskScheduler.setPoolSize(environment.getProperty(RECEIVE_MESSAGE_POOL_SIZE, Integer.class, DEFAULT_RECEIVE_MESSAGE_POOL_SIZE)); threadPoolTaskScheduler.afterPropertiesSet(); DirectChannel directChannel = new DirectChannel(); directChannel.subscribe(new MessageHandler() { @Override public void handleMessage(Message<?> message) throws org.springframework.messaging.MessagingException { LOGGER.info("Message: " + message); } }); imapIdleChannelAdapter = new ImapIdleChannelAdapter(imapMailReceiver); imapIdleChannelAdapter.setAutoStartup(true); imapIdleChannelAdapter.setShouldReconnectAutomatically(true); imapIdleChannelAdapter.setTaskScheduler(threadPoolTaskScheduler); imapIdleChannelAdapter.setOutputChannel(directChannel); imapIdleChannelAdapter.start(); } catch (IllegalStateException iex){ LOGGER.debug("Receiving messages failed", iex); iex.printStackTrace(); imapIdleChannelAdapter.stop(); try{ imapMailReceiver.destroy(); } catch (Exception ex){ LOGGER.debug("Impossible destroy imapMailReceiver", ex); ex.printStackTrace(); } } catch (UnsupportedEncodingException uex) { LOGGER.debug("UnsupportedEncoding Exception", uex); uex.printStackTrace(); } }
我的堆栈跟踪
09:13:27,429 INFO ImapMailReceiver:251 - attempting to receive mail from folder [INBOX] 09:13:34,840 WARN ImapIdleChannelAdapter:230 - error occurred in idle task javax.mail.MessagingException: A13 NO STORE attempt on READ-ONLY folder (Failure) [THROTTLED]; nested exception is: com.sun.mail.iap.CommandFailedException: A13 NO STORE attempt on READ-ONLY folder (Failure) [THROTTLED] at com.sun.mail.imap.IMAPMessage.setFlags(IMAPMessage.java:858) at javax.mail.Message.setFlag(Message.java:574) at org.springframework.integration.mail.AbstractMailReceiver.setMessageFlags(AbstractMailReceiver.java:317) at org.springframework.integration.mail.AbstractMailReceiver.postProcessFilteredMessages(AbstractMailReceiver.java:283) at org.springframework.integration.mail.AbstractMailReceiver.receive(AbstractMailReceiver.java:272) at org.springframework.integration.mail.ImapIdleChannelAdapter$IdleTask.run(ImapIdleChannelAdapter.java:216) at org.springframework.integration.mail.ImapIdleChannelAdapter$ReceivingTask.run(ImapIdleChannelAdapter.java:184) at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334) at java.util.concurrent.FutureTask.run(FutureTask.java:166) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:178) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:292) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:722)
我也发现这样的决定
http://harikrishnan83.wordpress.com/2009/01/24/access-gmail-with-imap-using- java-mail-api/ http://metoojava.wordpress.com/2010/03/21/java- 使用Javamailapi接收邮件的代码
但是我不明白为什么人们使用这种方式来获取消息(主要来源是这个决定,因为我什至在Spring Pro Integration和Spring文档中都找不到这种解决方案)
请,任何人都可以向我解释1)在这种情况下,我应该使用ImapIdleChannelAdapter,并且当使用Session进行存储和连接到邮箱时。2)为什么现在出现异常“不对只读文件夹尝试存储”
您应该打电话imapMailReceiver.afterPropertiesSet(),这会切换this.folderOpenMode = Folder.READ_WRITE;。就您而言,它看起来就在这里:
imapMailReceiver.afterPropertiesSet()
this.folderOpenMode = Folder.READ_WRITE;
imapMailReceiver.setJavaMailAuthenticator(new Authenticator() { ... }); imapMailReceiver.afterPropertiesSet();
实际上,几乎所有的Spring Integration组件都应配置为Spring Bean,并且Container将注意它们的初始化。新的4.0版本为JavaConfig提供了足够的选项:https ://spring.io/blog/2014/04/30/spring- integration-4-0-released 。
对我来说,目前尚不清楚为什么默认情况下是这样,Folder.READ_ONLY并且对此没有任何影响。
Folder.READ_ONLY
随意提出JIRA问题:https : //jira.spring.io/browse/INT
在这种情况下,我应该使用ImapIdleChannelAdapter,而在使用Session进行存储和连接到邮箱时。
实际上,这取决于您的邮件提供商。Spring Integration提供了两个组件:Pop3MailReceiver和ImapMailReceiver。当然Imap更好,因为它不将消息提取到本地目录并支持Listener。Pop3您应该定期ping通。
Pop3MailReceiver
ImapMailReceiver
Listener