2010-04-15 11 views
14

Évidemment, il n'est pas si difficile d'envoyer des e-mails depuis une application Java EE via JavaMail. Ce qui m'intéresse est le meilleur modèle pour recevoir emails (les rebonds de notification, la plupart du temps)? Je ne suis pas intéressé par les approches IMAP/POP3 (interroger la boîte de réception) - mon application doit réagir aux e-mails entrants.Comment recevoir des e-mails dans une application Java EE

Une approche que je pouvais penser serait

  • Conserver MTA existant (Postfix linux dans mon cas) - équipe> ops sait déjà comment configurer/faire fonctionner
  • Pour chaque courrier qui arrive, générer une application Java qui reçoit les données et l'envoie via JMS. Je pourrais faire cela via une entrée dans/etc/aliases comme myuser: "|/path/to/javahelper" avec javahelper appelant l'application Java, en passant STDIN le long.
  • MDB (partie de l'application Java EE) reçoit le message JMS, l'analyse, détecte le message de rebond et agit en conséquence.

Une autre approche pourrait être

  • Ouvrez une prise réseau d'écoute sur le port 25 sur le conteneur d'applications Java EE.
  • Associez un SessionBean au socket. Bean fait partie de l'application Java EE et peut analyser/détecter les bounces/gérer les messages directement.
  • Conserver MTA existant comme relais entrant, faire tout son filtrage de sécurité/spam, mais des e-mails avant de myuser (qui passent le filtre) au conteneur d'applications Java EE, le port 25.

La première approche que je fait avant (bien que dans une langue/configuration différente). Du point de vue de la performance et du point de vue de la propreté (perçue), je pense que la deuxième approche est meilleure, mais cela nécessiterait que je fournisse une implémentation de transport SMTP appropriée. Aussi, je ne sais pas s'il est possible de connecter un socket réseau avec un bean ...

Quelle est votre recommandation? Avez-vous des détails sur la deuxième approche?

+0

Quelle approche avez-vous finalement choisi? – Theo

+0

Le projet a été sur une backburner pendant un certain temps. En ce moment, je travaille à nouveau sur ce sujet, mais je n'ai pas encore implémenté la partie réceptrice. Jusqu'à présent, mon plan est de suivre la suggestion de sleske et de scanner une boîte mail à intervalles réguliers via IMAP. – Hank

+0

Débarrassez-vous du jms dans l'op 1 et envoyez-le simplement via curl/http spawned à un endpoint de repos et vous pouvez couper un morceau (JMS/MDB) de conf/complexité sur. – alphazero

Répondre

8

Je ne pense pas que la deuxième approche soit "plus propre". Au contraire, il vous oblige à mettre en œuvre une partie importante d'un MTA standard, donc je recommanderais contre. Je crois que l'interrogation d'un serveur POP/IMAP est en fait le moyen le plus propre de le faire. Pourquoi avez-vous décidé contre? Si le serveur POP/IMAP et votre service sont dans le même réseau local (ou même sur le même maching), un sondage sera assez bon marché. Vous pouvez le faire tous les 10-20s pour un retard minimum, cela ne devrait pas causer de problèmes. Bien que cela puisse sembler un peu techniquement inélégant, vous utiliserez un protocole d'interopération standard (POP3/IMAP), qui vous donne de la flexibilité tout en évitant de réimplémenter un serveur de messagerie.

L'approche de la ponte d'une application Java semble aussi viable, mais je préférerais le vote, parce que:

a) L'interface que vous utilisez (POP3/IMAP) est plus standardisée, alors que l'interface que vous utilisez pour "brancher" au serveur de messagerie sera spécifique au serveur (sur Unix, vous pouvez utiliser par exemple procmail, mais vous dépendez toujours de logiciels spécifiques)

b) Lancer un processus séparé par courrier aura probablement beaucoup plus de frais généraux que vote.Incidemment: Une troisième approche consisterait à vider les courriers entrants en tant que fichiers dans un répertoire "entrant" (de nombreux serveurs de courrier peuvent le faire), puis à interroger le répertoire. L'interrogation d'un répertoire sera encore moins coûteuse que l'interrogation d'un serveur. Méfiez-vous des problèmes de synchronisation (la lecture du courrier demi-écrit, plusieurs lecteurs simultanés lisant le même fichier courrier ...)

Mon expérience:

je les systèmes mis en œuvre à l'aide de deux approches (sondage IMAP, et fraye un séparée processus). L'interrogation portait sur une application Java relativement volumineuse qui traitait les données envoyées par les personnes à une boîte aux lettres. Je n'ai rencontré aucun problème lors des sondages. L'approche de frai était pour un petit script Perl; Je l'ai juste fait parce que c'était un programme simple qui ne traitait que quelques mails par jour, et brancher sur le mail server était plus facile que de faire IMAP en Perl.

+0

@sleske: Thx pour la réponse détaillée! Malheureusement, le MTA ne fournit pas d'installations POP3/IMAP (aujourd'hui) ... Je vais réfléchir à quelle partie est la plus facile. – Hank

7

Le "bon" moyen selon l'architecture Java EE serait d'avoir un connecteur JCA pour faire une connexion entrante/sortante avec le serveur SMTP.

Le connecteur JCA peut faire ce que vous voulez, y compris le filetage et la connexion à des systèmes externes avec des prises. En fait JMS est juste un type spécial de connecteur JCA qui se connecte au courtier JMS et délivre un message à MDB "régulier". Un connecteur JCA peut ensuite interroger le serveur SMTP et envoyer le message à un MDB personnalisé.

Le meilleur document à propos de JCA est le Creating Resource Adapters with J2EE Connector Architecture 1.5, et il utilise en fait l'exemple de la distribution de courrier électronique. Bonne chance :) Je vous suggère de le regarder. Le code peut être trouvé dans le cadre des exemples Java EE et utilise JavaMail, mais je ne sais pas s'il est prêt pour la production.

connexes:

+0

Cela semble assez compliqué ... Pourquoi ne pas simplement implémenter un EJB sans état qui vérifie périodiquement les nouveaux Emails (en utilisant le service de minuterie)? L'approche JCA m'apporte-t-elle des avantages supplémentaires en termes de performance, de fiabilité, etc.? – Theo

+0

@Theo Vous pouvez en effet utiliser un temporisateur EJB ou générer un thread à partir d'un 'ServletContextListener'. J'ai utilisé les deux pour les travaux d'arrière-plan, cela fonctionne, mais selon la "philosophie" de JEE une telle infrastructure devrait être gérée par le serveur d'application lui-même ou un connecteur JCA, et ne pas faire partie du code d'application. En outre, les paramètres d'infrastructure tels que les paramètres SMTP ne doivent pas être considérés comme les paramètres "business" avec 'env-entry'. Mais en fin de compte, c'est une question de pureté de conception, et ce que vous voulez que le travail soit fait. Alors allez-y avec ce qui est le plus simple pour vous. – ewernli

+0

ewernli est 100% correct ici (en fait, cela ressemble à un très grand projet OSS potentiel). * tout ce que vous faites en dehors du jeu de fonctionnalités géré par conteneur * n'est pas * couvert par le SLA d'un serveur d'applications JEE. Cela devient particulièrement critique si vous commencez à distribuer à travers les conteneurs. – alphazero

2

L'utilisation d'un ESB - autonome ou embeded. Un ESB apporte des concepts liés au flux, tels que la transformation et le routage, à une architecture orientée service (ESB) qui permet une abstraction pour les points de terminaison. "

Par exemple MULE « Mule ESB est le plus largement utilisé open source ESB. Une plate-forme d'intégration légère et le conteneur de service, Mule ESB offre des fonctionnalités pour les services Web, le routage des messages, la médiation, la transformation et la gestion des transactions, aider les développeurs intégrer leurs applications en heures, des semaines »

Comment recevoir des e-mails via mule http://books.dzone.com/articles/mule-messaging-chapter?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+zones%2Fsoa+(SOA+Zone)

Voici simplement la configuration qui envoient un message JMS comme réaction sur le message reçu (il est tout ce que vous avez besoin) - définir entrant (imap/pop3/etc) - définir sortant.

<imap:inbound-endpoint user="bob" password="password" host="localhost" port="65433" checkFrequency="3000"/> 
<jms:outbound-endpoint queue="my.destination" connector-ref="jmsQueueConnector"/> 
+0

Votre exemple avec 'imap: inbound-endpoint' récupérera les mails via IMAP, ce qui est exactement ce que l'OP a explicitement rejeté. – sleske

+1

En fait, à partir des documents, il semble que Mule ne supporte même pas le SMTP entrant, seulement sortant. Donc, Mule pourrait ne pas aider ici ... – sleske

+0

Bien que ce n'est pas ce que l'OP chercherait, je trouve que c'est une solution plus appropriée pour une entreprise car il découplage de la messagerie électronique à partir de l'application, l'application peut exposer un point de terminaison de service pour les messages. –

3

Qu'en est-il d'Apache James?

il implémente toute la pile, et vous laisse réagir au courrier entrant avec une approche de type servlet; il est open source, entièrement apache sous licence (donc peut être utilisé dans les produits commerciaux), et a déjà été testé pendant des années.

+0

Super idée, je vais regarder dedans! On dirait que cela pourrait implémenter mon approche basée sur les événements. – Hank