123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435 |
- ---
- title: Sending Email From Java Applications
- order: 12
- layout: page
- ---
-
- [[sending-email-from-java-applications]]
- Sending email from Java Applications
- ------------------------------------
-
- [[introduction]]
- Introduction
- ^^^^^^^^^^^^
-
- Sending email is a common feature required in many business applications.
- From simple notifications containing plain text to complex reports with
- links and multiple attachments, email is a common way of asynchronous
- communication with end users.
-
- This tutorial shows how to send email messages in two different ways:
-
- 1. Using the Apache Commons Email library which offers a simplified API on top of the JavaMail API.
- 2. Using Spring Mail Support, a utility library that encapsulates the specifics of the mailing system, also implemented on top of the JavaMail API.
-
- Although
- email operations include sending, receiving, deleting, setting flags,
- and others depending on the specific email server in use, this tutorial
- only discusses email sending through SMTP.
-
- [[how-does-email-work]]
- How does Email Work?
- ~~~~~~~~~~~~~~~~~~~~
-
- Let’s start
- with a quick overview of the email communication process. It all begins
- with the end user composing a message using a client desktop or web
- application. The message is sent through multiple networking devices
- until it reaches its destination at the recipient’s machine. The
- relevant elements of this process are depicted in the following figure:
-
- image:https://lh5.googleusercontent.com/GbbTWnXnPml4ijiQU1mMO8tkmGSGAcmpXEGwHQJwGOFGGI3zD98_rgYaGi-0OX18M9iTtkHyif8FnJNdKX1ubdE8MXIQ4k-Ww5qu0-MC4aoOhiqjKz56p8KLyN-QdonMZzSKEEGS[javamail-tutorial]
-
- Once the end
- user has triggered the action to send the email, the client application
- connects to its configured email server, the SMTP Server, which can be
- described as a program capable of communicating with other SMTP Servers
- using the Simple Mail Transfer Protocol (SMTP). This SMTP Server can be
- your own server running software, such as Apache James Server, Postfix,
- Sendmail, qmail, or a server managed by a third party, such as Gmail,
- Outlook, and Yahoo Mail.
-
- Your SMTP
- Server (managed by yourself or by a third party) sends the email message
- to the recipient’s SMTP Server. Once the message reaches its
- destination, it is stored in the recipient’s inbox at the recipient’s
- SMTP Server. Finally, the recipient can read the message by requesting
- it from the SMTP Server.
-
- Nowadays,
- SMTP is used to send email messages and IMAP (Internet Message Access
- Protocol) or POP (Post Office Protocol) to receive messages. In this
- case, your client application will use SMTP to send the message and the
- recipient’s SMTP Server will use SMTP to receive the message and IMAP or
- POP to serve the message when the recipient requests it. You don’t need
- to understand the specifics of these protocols in order to send email
- from a Java application but you might want to understand them deeper, if
- you are planning to implement operations such as receiving, deleting,
- and setting flags, or if your applications require sending zillions of
- emails in a batch.
-
- [[configuring-a-test-smtp-server]]
- Configuring a Test SMTP Server
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- For the
- purposes of this tutorial, we are going to use FakeSMTP, a free email
- server that offers a convenient GUI for testing email sending. You can
- download it from the following website: https://nilhcem.github.io/FakeSMTP/download.html[https://nilhcem.github.io/FakeSMTP/download.html]
-
- Extract the
- content of the downloaded zip file and execute the extracted jar. You
- can configure a port in the Listening port option (we will use 9090 in
- this tutorial). Once ready, click the Start server button to start
- getting emails.
-
- Please note
- that with FakeSMTP you don’t need to provide any authentication values
- (they will be ignored).
-
- [[javamail-api]]
- JavaMail API
- ~~~~~~~~~~~~
-
- The JavaMail
- API is defined by the JSR 919 and is included in Java EE (but not in EJB
- Lite nor Java EE Web Profile). It provides an abstraction over mail
- systems which makes its API more verbose than those of Apache Commons
- Email and Spring Mail Support. We are not covering JavaMail in this
- tutorial. However, we provide an example application that uses JavaMail
- to send emails. You can get the code from the following link: https://github.com/alejandro-du/java-email-tutorial/blob/master/javamail-example/src/main/java/com/example/javamail/JavaMailService.java[https://github.com/alejandro-du/java-email-tutorial/blob/master/javamail-example/src/main/java/com/example/javamail/JavaMailService.java]
-
- [[apache-commons-email]]
- Apache Commons Email
- ~~~~~~~~~~~~~~~~~~~~
-
- Apache
- Commons Email is built on top of JavaMail and hides much of its
- complexity. Therefore, it offers an API that simplifies the code to
- implement email sending from Java applications.
-
- You must
- download the Commons Email jar file from the following link:
- https://commons.apache.org/proper/commons-email/download_email.cgi[https://commons.apache.org/proper/commons-email/download_email.cgi],
- or add the dependency using a dependency management system. For example,
- if you are using Maven, you can add the following to your pom.xml:
-
- [source, xml]
- ....
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-email</artifactId>
- <version>1.4</version>
- </dependency>
- ....
-
-
- With Commons
- Email, you can send emails with HTML content using the `HtmlEmail` class.
- This class offers an abstraction to send emails with attachments. For
- example, during testing you can configure the `HtmlEmail` instance as
- follows:
-
- [source,java]
- ....
- HtmlEmail email = new HtmlEmail();
- email.setHostName("localhost");
- email.setSmtpPort(9090);
- email.setAuthentication()"sender@test.com", "password");
- ....
-
- Or if you want to use Gmail:
-
- [source,java]
- ....
- HtmlEmail email = new HtmlEmail();
- email.setHostName("smtp.gmail.com");
- email.setSmtpPort(465);
- email.setSSLOnConnect(true);
- email.setAuthentication("your-account-name@gmail.com", "your-password");
- ....
-
- Keep in mind
- that hard-coding connection parameters like this is not good practice.
- Instead, you should read the values from an external source (such as a
- properties file) so that you can use different configurations for
- different environments (development, testing, production).
-
- You can use
- the email instance to set the sender’s email address, add recipients,
- and set the subject and the text of the message:
-
- [source,java]
- ....
- email.setFrom("sender@test.com");
- email.addTo("recipient1@test.com", "recipient2@test.com");
- email.setSubject("The subject");
- email.setHtmlMsg("This is the message.");
- ....
-
- The `HtmlEmail`
- class also exposes the attach method to add attachments to the message.
- You can provide these attachments as an `InputStream` so that its content
- can be dynamically generated at runtime if required (`FileInputStream` is
- always an option in case you have `File` instances instead):
-
- [source,java]
- ....
- ByteArrayDataSource dataSource = new ByteArrayDataSource(inputStream, "text/plain");
- DataHandler dataHandler = new DataHandler(dataSource);
- email.attach(dataSource, "attachment.txt", "description");
- ....
-
-
- The `attach`
- method is overloaded with multiple implementations offering different
- ways to attach files. The one used in the previous example requires to
- specify a description for the attachment.
-
- You can find
- a complete implementation of a utility class that implements email
- sending using the Commons Email in the following link: https://github.com/alejandro-du/java-email-tutorial/blob/master/commons-email-example/src/main/java/com/example/javamail/CommonsEmailService.java[https://github.com/alejandro-du/java-email-tutorial/blob/master/commons-email-example/src/main/java/com/example/javamail/CommonsEmailService.java]
-
- [[spring-email-support]]
- Spring Email Support
- ~~~~~~~~~~~~~~~~~~~~
-
- Similarly to
- the Apache Commons Email library, Spring offers an API on top of
- JavaMail which abstracts away the details of the mailing system. You
- need to add the `spring-context-support` dependency using Maven or Gradle.
- There is no official download site for this dependency, but you can
- download it directly from the following link if required: http://mvnrepository.com/artifact/org.springframework/spring-context-support/4.2.4.RELEASE[http://mvnrepository.com/artifact/org.springframework/spring-context-support/4.2.4.RELEASE].
-
- If you are
- using Maven you can add the following dependency to your pom.xml:
-
- [source,xml]
- ....
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context-support</artifactId>
- <version>4.2.4.RELEASE</version>
- </dependency>
- ....
-
- You start by
- obtaining an implementation of the `MailSender` interface. Spring provides
- the `JavaMailSenderImpl` class that implements `MailSender`. You can obtain
- an instance of this class either by configuring and injecting a bean, if
- you are already using Spring Framework and have configured an
- application context, or by direct instantiation:
-
- [source,java]
- ....
- JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
- ....
-
- The
- connection to the SMTP server is configured using properties. The
- following example shows how to configure the `mailSender` to connect to
- Gmail’s SMTP server:
-
- [source,java]
- ....
- Properties properties = new Properties();
- properties.put("mail.smtp.host", "smtp.gmail.com");
- properties.put("mail.smtp.port", "465");
- properties.put("mail.smtp.ssl.enable", "true");
-
- mailSender.setJavaMailProperties(properties);
- ....
-
- Alternatively,
- you can use methods defined in the `MailSender` interface to configure the
- host and port, but in the case of SMTP servers using SSL, you will have
- to provide at least the `mail.smtp.ssl.enable` property through a
- `Properties` object. For this reason, we prefer to configure all the
- settings using properties in this example.
-
- The authentication credentials are configured using the `MailSender` instance
- as follows:
-
- [source,java]
- ....
- mailSender.setUsername("sender@test.com");
- mailSender.setPassword("password");
- ....
-
- The next step is to create a `MimeMessage` and a `MimeMessageHelper`:
-
- [source,java]
- ....
- MimeMessage message = mailSender.createMimeMessage();
- MimeMessageHelper helper = new MimeMessageHelper("The message body", true);
- ....
-
- The second
- parameter is set to true to create a multipart message that will allow
- us to add attachments later. The `MimeMessageHelper` exposes a handful of
- methods to directly set up the message:
-
- [source,java]
- ....
- helper.setFrom("sender@test.com");
- helper.setSubject("subject");
- helper.setText(text, true); // true to activate multipart
- helper.addTo("recipient@test.com");
- ....
-
- There are
- several overloaded methods in the `MimeMessageHelper` that provide
- different ways to attach files. The following example uses the
- `ByteArrayDataSource` class to provide an attachment from an `InputStream`:
-
- [source,java]
- ....
- ByteArrayDataSource dataSource = new ByteArrayDataSource(inputStream, "text/plain");
- helper.addAttachment("file.txt", dataSource);
- ....
-
- Finally, you can send the email using the `MailSender` instance:
-
- [source,java]
- ....
- mailSender.send(message);
- ....
-
-
- You can find
- a complete implementation of a utility class that implements email
- sending using Spring Email Support in the following link: https://github.com/alejandro-du/java-email-tutorial/blob/master/spring-mail-example/src/main/java/com/example/javamail/SpringEmailService.java[https://github.com/alejandro-du/java-email-tutorial/blob/master/spring-mail-example/src/main/java/com/example/javamail/SpringEmailService.java]
-
- [[an-example-web-application]]
- An Example Web Application
- ~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Let’s create
- a Java web application to test this functionality. The application
- consists of a text field where users can type an email address and a
- button that will send an email with an attachment to the specified
- address.
-
- We are going
- to use the https://vaadin.com[Vaadin Framework] which allows us to quickly create a web
- application by using only the Java Programming Language. This way, we
- don’t need to worry about writing any HTML or JavaScript at all.
-
- Although most
- IDEs have plugins to easily generate a new Vaadin project, we are going
- to use a Maven archetype to generate the project that you can later
- import into your favorite IDE. You can create a new Vaadin project with
- Maven using the following command line:
-
- [source]
- ....
- mvn archetype:generate -DarchetypeGroupId=com.vaadin -DarchetypeArtifactId=vaadin-archetype-application -DarchetypeVersion=7.6.2
- ....
-
- After
- specifying a group and artifact id, you can run `mvn clean install` to
- compile the project and `mvn jetty:run` to deploy and run the application.
- Open your browser and navigate to http://localhost:8080[http://localhost:8080] to see the application
- running.
-
- Open the `MyUI.java` file (it should be the only Java file in the project) and change the `init` method to the following:
-
- [source,java]
- ....
- //... imports mostly from com.vaadin package
-
- public class MyUI extends UI {
- @Override
- protected void init(VaadinRequest vaadinRequest) {
- // the text field where users will specify their email address
- TextField textField = new TextField("Your email:");
-
- // a button with a click listener that sends the email
- Button button = new Button("Send me the PDF", e -> sendEmail(textField.getValue()));
-
- // a layout containing the previous components
- VerticalLayout layout = new VerticalLayout(textField, button);
- layout.setMargin(true);
- layout.setSpacing(true);
-
- setContent(layout); // sets the content for this UI
- }
- ...
- }
- ....
-
- Add the missing `sendEmail` method and implement it as follows:
-
- [source,java]
- ....
- private void sendEmail(String to) {
- try {
- // all values as variables to clarify its usage
- InputStream inputStream = getClass().getResourceAsStream("/dock-magazine.pdf");
- String from = "sender@test.com";
- String subject = "Your PDF";
- String text = "Here there is your <b>PDF</b> file!";
- String fileName = "file.pdf";
- String mimeType = "application/pdf";
-
- CommonsEmailService.send(from, to, subject, text, inputStream, fileName, mimeType);
-
- Notification.show("Email sent");
- } catch (MessagingException | IOException e) {
- e.printStackTrace();
- Notification.show("Error sending the email", Notification.Type.ERROR_MESSAGE);
- }
- }
- ....
-
-
- At this point
- you might want to create the missing `CommonsEmailService` class (or
- `SpringMailService` class) and implement the send method as an exercise.
- But if you prefer, you can take the example implementation from the
- following link: https://github.com/alejandro-du/java-email-tutorial/blob/master/commons-email-example/src/main/java/com/example/javamail/CommonsEmailService.java[https://github.com/alejandro-du/java-email-tutorial/blob/master/commons-email-example/src/main/java/com/example/javamail/CommonsEmailService.java]
-
- Finally, add
- a PDF file with the name file.pdf in the resources directory of your
- Maven project. You may want to use a small file so that SMTP servers
- would be able to accept it.
-
- Stop the
- Jetty server if necessary, run `mvn clean install` again, and reload the
- web page in the browser. The following is a screenshot of the web
- application: image:https://lh5.googleusercontent.com/zcy_LwtCa9TW-sP3phTlczRP9lBvE9ozaxd0Ae4yJghOjQnAjxOlhYp2n5ruLiLlroZ9HW_LEoJN-5qPJI60rXMiFvGuHcibvP5txCMhiS9ZPn1wCMYkN43Zkjqbuw1kTi0nXn_v[screenshot.png,width=622,height=433]
-
- If you have
- FakeSMTP running, you should be able to see the email messages sent
- through the web application.
-
- [[which-approach-to-use]]
- Which Approach to Use?
- ~~~~~~~~~~~~~~~~~~~~~~
-
- Choosing an
- option depends on different factors. However, I would recommend to use
- Spring Email Support if you are developing a Spring application. If not,
- go with Apache Commons Email, it offers the most intuitive API. Also,
- Apache Commons Email jar is lighter than the spring-context-support jar,
- as the later includes more than just the email support classes. Using
- the JavaMail API directly may be convenient only when you need lower
- level interaction with the mailing system.
-
- You can experiment with the code by downloading the example web applications
- from GitHub:
-
- [source]
- ....
- $ git clone https://github.com/alejandro-du/java-email-tutorial
- $ cd java-email-tutorial
- $ cd commons-email-example
- # (Or cd spring-mail-example)
-
- $ mvn clean install
- $ mvn jetty:run
- ....
-
-
- Don’t forget to configure run FakeSMTP before using the web application deployed at
- http://localhost:8080[http://localhost:8080].
|