# IMAP Anmeldung in EJB - Objekt speichern und ständige Anmeldung verhindern



## beta20 (27. Aug 2018)

Hallo zusammen, 

ich habe eine JSF / EJB - Anwendung. In dieser kann sich jeder User bei seinem Emailprovider anmelden und Email versenden / abrufen über meine eigene JSF - Applikation.
Das funktioniert auch alles einwandfrei.
Ich habe nur das Problem, dass ich verschiedene Methoden habe, die jeweils eine Connection zum IMAP - Server aufbauen und ich dann irgendwann in eine Exception hereinlaufe, dass ich mich in der letzten Zeit zu oft versucht habe zu connecten.

Ich habe Methoden um:
- Verschiedene IMAP - Ordner zu öffnen (INBOX, Sent, Draft etc....)
-> Erfordert pro Ordner eine IMAP - Anmeldung

- Alle Ordnername auszugeben
-> Erfordert eine IMAP - Anmeldung

Was ich also brauche ist, dass die Connection (Store Object?) irgendwo für die Session gespeichert wird und demnach nicht ständig eine neue Verbindung zum IMAP - Server aufgebaut werden muss.

Ich habe schon versucht meine @EJB - Klasse mit @stateful zu deklarieren, das funktioniert aber auch nicht. Heißt das Objekt ist dann doch NULL beim erneuten Versuch...
Desweiteren habe ich in der @EJB - Klasse eine Property vom Typ "Store store = new Store()" angelegt.
Ich prüfe dann bei jeder Methode (Aufruf jeweiliger Folder etc.), ob das Objekt "store" nicht NULL ist. Wenn ja, dann melde mich an, wenn nicht, dann nehme das gefüllte Store - Objekt.

Habt ihr eine Idee wie ich das Problem lösen kann?


----------



## Flown (27. Aug 2018)

Naja mit @stateful sollte das schon funktionieren, wie sieht denn dein EJB aus?


----------



## beta20 (29. Aug 2018)

```
@javax.ejb.Stateful
public class EmailReaderServiceBean implements Serializable, EmailReaderService {

   private static final long serialVersionUID = 2115977542650719300L;
   private Store currentStore;

    public Store getCurrentStore() {
       return currentStore;
   }

   public void setCurrentStore(Store currentStore) {
       this.currentStore = currentStore;
   }
{
```

-> In currentStore wird die Store gespeichert...

und hier das Interface dazu:

```
public interface EmailReaderService {

    List<Message> findAllEmailFromEmailAddress(EmailSetting emailSetting, String searchEmailAddress, String inboxName) throws Exception;

    Folder getSentFolder(Folder[] folders) throws MessagingException;
    Folder getImportantFolder(Folder[] folders) throws MessagingException;
    Folder getJunkFolder(Folder[] folders) throws MessagingException;
    Folder getFlaggedFolder(Folder[] folders) throws MessagingException;
    Folder getTrashFolder(Folder[] folders) throws MessagingException;
    Folder getDraftsFolder(Folder[] folders) throws MessagingException;
......

}
```

Irgendwelche Ideen?


----------



## Flown (29. Aug 2018)

Und wie wird dein EJB im Controller reingebracht?


----------



## beta20 (29. Aug 2018)

Über:


```
@EJB
private EmailReaderService  emailReaderService
```

oder muss ich die Klasse verwenden und nicht das Interface, also:

```
@EJB
private EmailReaderServiceBean  emailReaderServiceBean
```


----------



## Flown (29. Aug 2018)

Ein kleines Beispielprogamm könnte bei dir helfen. Denn so sollte es eigentlich funktionieren.


----------



## beta20 (30. Aug 2018)

Frage:
Muss mein Controller zwingend @SessionScoped haben oder geht auch @ViewScoped?


----------



## Xyz1 (31. Aug 2018)

beta20 hat gesagt.:


> - Verschiedene IMAP - Ordner zu öffnen (INBOX, Sent, Draft etc....)
> -> Erfordert pro Ordner eine IMAP - Anmeldung


nein


beta20 hat gesagt.:


> - Alle Ordnername auszugeben
> -> Erfordert eine IMAP - Anmeldung


und nein

Du hast da ist und soll verwechselt.



beta20 hat gesagt.:


> Habt ihr eine Idee wie ich das Problem lösen kann?


ja indem Store nur einmal angelegt wird. Wo haperts?


----------



## Flown (31. Aug 2018)

beta20 hat gesagt.:


> Muss mein Controller zwingend @SessionScoped haben oder geht auch @ViewScoped?


Das hat nichts mit dem zutun wie langlebig eine EJB ist.


----------



## beta20 (13. Sep 2018)

Leider funktioniert das ganze immer noch nicht und ich sehe in meinem Loggin, dann immer wieder versucht wird sich zu connection....

Hier mein Code:

Das Interface from EJB

```
public interface EmailReaderService {
    List<Message> findAllEmailFromEmailAddress(EmailSetting emailSetting, String searchEmailAddress, String inboxName, String sortOrder, String sortField) throws Exception;
}
```


```
import javax.ejb.EJB;
import javax.ejb.LocalBean;
import javax.ejb.SessionContext;
import javax.ejb.Stateful;

@Stateful
@LocalBean
public class EmailReaderServiceBean {

    private static final long serialVersionUID = 2115977542650719300L;
    @Resource
    private SessionContext sessionContext;

    private Store currentStore;

    public Store getCurrentStore() {
        return currentStore;
    }

    public void setCurrentStore(Store currentStore) {
        this.currentStore = currentStore;
    }

/**
    * Anmelden bei Imap
    *
    * @param emailSetting
    * @return
    * @throws Exception
    */
   private Store connectImap(EmailSetting emailSetting) throws Exception {

       System.out.print("START CONNECT IMAP");

       if (currentStore != null)
           return currentStore;

       System.out.print("CONNECT IMAP ");

       Properties properties = new Properties();

       // server setting
       properties.put("mail.imap.host", emailSetting.getReceiverHost());
       properties.put("mail.imap.port", emailSetting.getReceiverPort());
       properties.setProperty("mail.store.protocol", "imaps");

       // Init 3600000 = 1h
       properties.setProperty("mail.imap.connectiontimeout", "3600000");
       properties.setProperty("mail.imap.timeout", "3600000");

       properties.put("mail.imap.ssl.enable", "false");
       properties.put("mail.imap.starttls.enable", "false");

       // SSL setting
       if (emailSetting.getReceiverEncoding().equals("SSL")) {
           properties.setProperty("mail.imap.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
           properties.setProperty("mail.imap.socketFactory.fallback", "false");
           properties.setProperty("mail.imap.socketFactory.port", String.valueOf(emailSetting.getReceiverPort()));
       }

       Session session = Session.getDefaultInstance(properties, null);
       // session.setDebug(true);

       // connects to the message store
       Store store = session.getStore("imap");

       // Password entschlüsseln
       String passwordEncrypt = PasswordHelperClass.encryptPassword(emailSetting.getPassword());

       int port = Integer.parseInt(emailSetting.getReceiverPort());

       if (!store.isConnected()) {
           store.connect(emailSetting.getReceiverHost(), port, emailSetting.getUsername(), passwordEncrypt);

           currentStore = store;
       }

       return store;
   }
```


Meine Erwartungshaltung ist, dass Store *currentStore* für jede User-Session gespeichert wird und demnach nur *1x beim ersten Anmelden* geholt wird...
Das ist aber leider nicht der Fall - es wird immer wieder die connectImap - Methode aufgerufen und currentStore scheint = null zu sein, sodass jedes Mal eine Anmeldung erfolgt...

Irgendeine Idee was falsch ist?


----------



## mihe7 (13. Sep 2018)

Du dürftest die EJB @SessionScoped annotieren müssen, damit die HTTP-Session zum Client der Bean wird.


----------



## beta20 (13. Sep 2018)

@SessionScoped geht das wirklich bei einer EJB? Ich dachte nur im Controller / ManagedBean...


----------



## mihe7 (14. Sep 2018)

Ja, das geht.


----------



## beta20 (21. Mrz 2019)

Stimmt das dann so:


```
@Stateful
@LocalBean
@SessionScoped
public class EmailReaderServiceBean {
....
```

Im Moment läuft es OHNE das Interface ab, ist das überhaupt richtig. Also OHNE dieses hier:

```
public interface EmailReaderService {
    List<Message> findAllEmailFromEmailAddress(EmailSetting emailSetting, String searchEmailAddress, String inboxName, String sortOrder, String sortField) throws Exception;
}
```


----------



## thecain (21. Mrz 2019)

Wenn du nicht mehrere verschiedene Implementationen von EmailReaderService hast, brauchst du eh kein Interface.


----------



## beta20 (21. Mrz 2019)

es sollen aber mehrerer User gleichzeitig die Funktionen nutzen...


----------



## mihe7 (21. Mrz 2019)

beta20 hat gesagt.:


> es sollen aber mehrerer User gleichzeitig die Funktionen nutzen...


Und, wo siehst Du ein Problem?


----------



## beta20 (21. Mrz 2019)

mihe7 hat gesagt.:


> Und, wo siehst Du ein Problem?


brauche ich deshalb ein Interface oder nicht?


----------



## mihe7 (21. Mrz 2019)

Nein.


----------

