April 1, 2011

Read emails from imap with Spring Intergration

What's the easiest way to read emails from IMAP account in Java? Depends what your background is. If you have any experience in Apache Camel, ServiceMix, Mule, you already know the answer. If you don't, and your application is using Spring already, Spring-Integration may be the solution for you.

It's not a one-liner like what you could do with Camel, but it's still quite easy to understand.

Spring Integration has great docs and there are nice tutorials around, but if you just want to get it running first and dig into the docs later, here is a quick example for you.

To make it work, you need three steps:

1. Add spring-integration to your pom
<properties>
    <spring.integration.version>2.0.3.RELEASE</spring.integration.version>
</properties>

<dependency>
      <groupId>org.springframework.integration</groupId>
      <artifactId>spring-integration-core</artifactId>
      <version>${spring.integration.version}</version>
</dependency>
<dependency>
      <groupId>org.springframework.integration</groupId>
      <artifactId>spring-integration-mail</artifactId>
      <version>${spring.integration.version}</version>
 </dependency>
2. Add IoC configuration
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mail="http://www.springframework.org/schema/integration/mail"
       xmlns:int="http://www.springframework.org/schema/integration"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
            http://www.springframework.org/schema/integration/mail
            http://www.springframework.org/schema/integration/mail/spring-integration-mail-2.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd">

    <util:properties id="javaMailProperties">
        <prop key="mail.imap.socketFactory.class">javax.net.ssl.SSLSocketFactory</prop>
        <prop key="mail.imap.socketFactory.fallback">false</prop>
        <prop key="mail.store.protocol">imaps</prop>
        <prop key="mail.debug">${imap.debug}</prop>
    </util:properties>

    <mail:inbound-channel-adapter id="imapAdapter" 
                                      store-uri="${imap.uri}"                                     
                                      channel="recieveEmailChannel"                                          
                                      should-delete-messages="false"
                                      should-mark-messages-as-read="true"                                      
                                      auto-startup="true"
                                      java-mail-properties="javaMailProperties">
        <int:poller fixed-delay="${imap.poolerSecondsDelay}" time-unit="SECONDS"/>
    </mail:inbound-channel-adapter>

    <int:channel id="recieveEmailChannel">        
        <int:interceptors>
            <int:wire-tap channel="logger"/>
        </int:interceptors>
    </int:channel>

    <int:logging-channel-adapter id="logger" level="DEBUG"/>

    <int:service-activator input-channel="recieveEmailChannel" ref="emailReceiverService" method="receive"/>

    <bean id="emailReceiverService" class="eu.solidcraft.emails.EmailReceiverService">
    </bean>
</beans>
In case you didn't notice: should-delete-messages="false" will make it not delete your emails from the inbox, and should-mark-messages-as-read="true" will mark them as read.

Example properties to get it to work with gmail (and check the inbox every 5 seconds) look like this:
imap.uri=imaps://username:password@imap.googlemail.com:993/INBOX
imap.debug=false
imap.poolerSecondsDelay=5
3. Parse incoming emails

All you need is a class, without any interfaces, that has a method with MimeMessage parameter (the name doesn't matter: you can configure it like in the xml above).

public class EmailReceiverService {
    public void receive(MimeMessage mimeMessage) {
...
Unfortunately, parsing MimeMessage is kind of tricky on it's own, but that's a completely different story.

4 comments:

  1. A very crisp post on reading emails ! Just the starter I was looking for. Thanks for the quickstart with Spring Integration. I'd take a look into a few other ones you've listed too.

    ReplyDelete
  2. Hi,
    Has anyone used this in SOA Suite 11g 11.1.5?

    Regards
    Oscar

    ReplyDelete
  3. Hi ,
    It was a very nice artical, i have implemeted this in my project. Thanks for the nice post.

    Now i have to poll multiple mail ids by reading from the database, can you please spread some light on it.

    Thanks,
    Venkat

    ReplyDelete