Wie schon im letzten Artikel (Sicherer Datenversand mit SFTP und Spring Batch ) befasst sich auch dieser Artikel mit einer nicht mehr ganz taufrischen, nichtsdestotrotz aber sehr wichtigen Technologie: E-Mail. In diesem Artikel wird gezeigt, wie sich der Versand von E-Mails mit Hilfe von Spring Batch einfach realisieren lässt. Spring Batch bringt hierfür schon einige fertige Komponenten mit, die man nur noch geeignet kombinieren muss.
Im folgenden Beispiel werden drei Beans deklariert, die beim E-Mail-Versand eine Rolle spielen:
mailSender
,sendMailTasklet
sowiesendMailService
.
Die Bean mailSender
muss nur deklariert werden, da wir hier eine Klasse aus dem Framework verwenden. Auf dieser Bean werden alle benötigten Parameter zur Verbindung mit dem Mail-Server konfiguriert.
Deklaration der Bean mailSender
1<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl"> 2 <property name="host" value="smtp.yourEmailDomain.de"/> 3 <property name="port" value="25"/> 4 <property name="username" value="yourUserName"/> 5 <property name="password" value="yourPassword"/> 6 <property name="javaMailProperties"> 7 <props> 8 <prop key="mail.smtp.auth">true</prop> 9 </props> 10 </property> 11</bean>
Das Tasklet wird von Spring Batch während der Ausführung aufgerufen (Methode execute
). Es koordiniert das Zusammenspiel der anderen beiden Beans. Des Weiteren werden auf dem Tasklet noch einige weitere Parameter für den E-Mail-Versand konfiguriert.
Deklaration des Tasklets
1<bean id="sendMailTasklet"> 2 <property name="mailSender" ref="mailSender"/> 3 <property name="sendMailService" ref="sendMailService"/> 4 <property name="senderAddress" value="sender@emailaddress.de"/> 5 <property name="recipient" value="recipient@emailaddress.de"/> 6 <property name="attachmentFilePath" value="/path/to/attachment/file/"/> 7</bean>
Java-Code für das Tasklet
1package de.batch.tasklets;
2
3import org.apache.commons.logging.Log;
4import org.apache.commons.logging.LogFactory;
5import org.springframework.batch.core.StepContribution;
6import org.springframework.batch.core.scope.context.ChunkContext;
7import org.springframework.batch.core.step.tasklet.Tasklet;
8import org.springframework.batch.repeat.RepeatStatus;
9import org.springframework.mail.javamail.JavaMailSender;
10
11import de.batch.mail.SendMailService;
12
13public class SendMailTasklet implements Tasklet {
14 private static final Log log = LogFactory.getLog(SendMailTasklet.class);
15 private SendMailService sendMailService;
16 private JavaMailSender mailSender;
17 private String senderAddress;
18 private String recipient;
19 private String attachmentFilePath;
20
21 public void setMailSender(JavaMailSender mailSender) {
22 this.mailSender = mailSender;
23 }
24 public void setSenderAddress(String senderAddress) {
25 this.senderAddress = senderAddress;
26 }
27
28 public void setRecipient(String recipient) {
29 this.recipient = recipient;
30 }
31
32 public void setAttachmentFilePath(String attachmentFilePath) {
33 this.attachmentFilePath = attachmentFilePath;
34 }
35
36 public void setSendMailService(SendMailService sendMailService) {
37 this.sendMailService = sendMailService;
38 }
39
40 @Override
41 public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
42 log.debug("execute(StepContribution contribution, ChunkContext chunkContext) begin");
43 sendMailService.setFields(mailSender, senderAddress, recipient, attachmentFilePath);
44 sendMailService.sendMail();
45 log.debug("execute(StepContribution contribution, ChunkContext chunkContext) end");
46 return RepeatStatus.FINISHED;
47 }
48}
Der sendMailService
schließlich kümmert sich um das Aufbereiten und Verschicken der E-Mail selbst.
Deklaration des Services
1<bean id="sendMailService" class="de.batch.mail.SendMailService" />
Der Java-Code für den Service
1package de.batch.mail;
2
3import java.io.File;
4import javax.ejb.Stateless;
5import javax.mail.Message;
6import javax.mail.internet.InternetAddress;
7import javax.mail.internet.MimeMessage;
8
9import org.apache.commons.logging.Log;
10import org.apache.commons.logging.LogFactory;
11import org.jboss.seam.annotations.Name;
12import org.springframework.core.io.FileSystemResource;
13import org.springframework.mail.MailException;
14import org.springframework.mail.javamail.JavaMailSender;
15import org.springframework.mail.javamail.MimeMessageHelper;
16import org.springframework.mail.javamail.MimeMessagePreparator;
17
18public class SendMailService {
19
20 private static final Log log = LogFactory.getLog(SendMailService.class);
21 private JavaMailSender mailSender;
22 private String senderAddress;
23 private String recipient;
24 private String attachmentFilePath;
25
26 // set the fields
27 public void setFields(JavaMailSender mailSender, String senderAddress, String recipient, String attachmentFilePath) {
28
29 this.mailSender = mailSender;
30 this.senderAddress = senderAddress;
31 this.recipient = recipient;
32 this.attachmentFilePath = attachmentFilePath;
33 }
34
35 public void sendMail() {
36 log.debug("send Email started");
37 // read directory
38 File directory = new File(attachmentFilePath);
39 // get file from directory
40 final File file = directory.listFiles(FILE_FILTER)[0];
41
42 MimeMessagePreparator preparator = new MimeMessagePreparator() {
43 public void prepare(MimeMessage mimeMessage) throws Exception {
44 mimeMessage.setRecipient(Message.RecipientType.TO, new InternetAddress(recipient));
45 mimeMessage.setFrom(new InternetAddress(senderAddress));
46 mimeMessage.setSubject("Neuer Report");
47 // MimeMessagesHelper is needed for the attachment. The Boolean value in
48 // constructor is for multipart/data = true
49 MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
50 helper.addAttachment(file.getName(), new FileSystemResource(file));
51 helper.setText("Text in Email Body");
52 }
53 };
54 try {
55 this.mailSender.send(preparator);
56 log.debug("send Email completed");
57 } catch (MailException ex) {
58 log.debug("send Email failed", ex);
59 }
60 }
61
62 public static FileFilter FILE_FILTER = new FileFilter() {
63 public boolean accept(File file) {
64 return !file.isDirectory();
65 }
66 };
67 }
Der Ablauf des Batch Jobs wird durch die Deklaration des Tags batch:job
angegeben. In unserem Fall ist hier nur das Tasklet als einziger Step anzugeben:
1<batch:job id="sendMailJob" restartable="false"> 2 <batch:step id="sendMailStep"> 3 <batch:tasklet ref="sendMailTasklet" /> 4 </batch:step> 5</batch:job>
Dies ist auch schon alles, was man zum Versand von E-Mails mit Spring Batch benötigt. Der Batch Job kann nun wie gehabt über die Kommandozeile/Shell (also z. B. auch durch einen cronjob) gestartet werden.
Weitere Beiträge
von Carsten Fröhlich
Dein Job bei codecentric?
Jobs
Agile Developer und Consultant (w/d/m)
Alle Standorte
Gemeinsam bessere Projekte umsetzen.
Wir helfen deinem Unternehmen.
Du stehst vor einer großen IT-Herausforderung? Wir sorgen für eine maßgeschneiderte Unterstützung. Informiere dich jetzt.
Hilf uns, noch besser zu werden.
Wir sind immer auf der Suche nach neuen Talenten. Auch für dich ist die passende Stelle dabei.
Blog-Autor*in
Carsten Fröhlich
Du hast noch Fragen zu diesem Thema? Dann sprich mich einfach an.
Du hast noch Fragen zu diesem Thema? Dann sprich mich einfach an.