This tutorial walks through the steps of developing a Java web application for the purpose of sending an e-mail with attachment based on Struts framework and JavaMail library. The e-mail form would look like this:
Currently, there is no plug-in for e-mailing in Struts, so the preferred choice is using JavaMail directly in Struts action class. Technically, the solution for this application is combination of two technologies:
We name the application as Struts2EmailApp - it would consist of the following source files:
Click Next to start building the application.
The following table lists all the jar files required for the application:
Jar files come with Struts2 distribution | commons-fileupload-1.2.2.jar |
commons-io-2.0.1.jar | |
commons-lang3-3.1.jar | |
commons-logging-1.1.1.jar | |
commons-logging-api-1.1.jar | |
freemarker-2.3.19.jar | |
javassist-3.11.0.GA.jar | |
ognl-3.0.5.jar | |
struts2-core-2.3.4.1.jar | |
xwork-core-2.3.4.1.jar | |
Jar file come with JavaMail distribution | mail.jar |
Click on the links to download the appropriate jar file. Copy these jar files into WEB-INF/libdirectory of the application. The project structure would look like following:
Create a Java file called EmailUtility.javawith the following code:
package net.codejava.struts2; import java.io.File; import java.io.IOException; import java.util.Date; import java.util.Properties; import javax.mail.Authenticator; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.Multipart; import javax.mail.PasswordAuthentication; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.AddressException; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; /** * A utility class for sending e-mail with attachment. * @author www.codejava.net * */ public class EmailUtility { public static void sendEmail(String host, String port, final String userName, final String password, String recipient, String subject, String message, File attachFile) throws AddressException, MessagingException { // sets SMTP server properties Properties properties = new Properties(); properties.put("mail.smtp.host", host); properties.put("mail.smtp.port", port); properties.put("mail.smtp.auth", "true"); properties.put("mail.smtp.starttls.enable", "true"); properties.put("mail.user", userName); properties.put("mail.password", password); // creates a new session with an authenticator Authenticator auth = new Authenticator() { public PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(userName, password); } }; Session session = Session.getInstance(properties, auth); // creates a new e-mail message Message msg = new MimeMessage(session); msg.setFrom(new InternetAddress(userName)); InternetAddress[] toAddresses = { new InternetAddress(recipient) }; msg.setRecipients(Message.RecipientType.TO, toAddresses); msg.setSubject(subject); msg.setSentDate(new Date()); // creates message part MimeBodyPart messageBodyPart = new MimeBodyPart(); messageBodyPart.setContent(message, "text/html"); // creates multi-part Multipart multipart = new MimeMultipart(); multipart.addBodyPart(messageBodyPart); // adds attachments if (attachFile != null) { MimeBodyPart attachPart = new MimeBodyPart(); try { attachPart.attachFile(attachFile); } catch (IOException ex) { ex.printStackTrace(); } multipart.addBodyPart(attachPart); } // sets the multi-part as e-mail's content msg.setContent(multipart); // sends the e-mail Transport.send(msg); } }
This utility class has only one static method sendEmail() that sends an e-mail from a SMTP server. It has the following parameters:
This class will be used by the action class which we will create later.
For in-depth information about sending e-mail with attachment, see this article: Send e-mail with attachment in Java.
Create a JSP file called EmailForm.jsp with the following code:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="s" uri="/struts-tags" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Struts2 - Email application</title> </head> <body> <center> <h1>Struts2 - Send e-mail with attachment</h1> <s:form action="doSendEmail" enctype="multipart/form-data" method="post"> <table border="0" width="80%" align="center"> <tr> <td> <s:textfield name="recipient" size="65" label="Recipient Address" /> </td> </tr> <tr> <td> <s:textfield name="subject" size="65" label="Subject" /> </td> </tr> <tr> <td> <s:textarea cols="50" rows="10" name="message" label="Message" /> </td> </tr> <tr> <td> <s:file name="fileUpload" size="60" label="Attach file" /> </td> </tr> <tr> <td> <s:submit value="Send E-mail" align="center" /> </td> </tr> </table> </s:form> </center> </body> </html>
We use Struts tags to create the form elements. Note that the form must have following attributes:
Create a Java file called SendEmailAction.java to represent a Struts action class, with the following code:
package net.codejava.struts2; import java.io.File; import java.io.IOException; import javax.mail.MessagingException; import javax.mail.internet.AddressException; import org.apache.commons.io.FileUtils; public class SendEmailAction { // SMTP properties - fetched from struts.xml private String host; private String port; private String userName; private String password; // file upload properties - fetched by interceptor fileUpload private File fileUpload; private String fileUploadFileName; private String fileUploadContentType; // e-mail fields - fetched from EmailForm.jsp private String recipient; private String subject; private String message; public String doSendEmail() throws IOException, AddressException, MessagingException { File saveFile = null; String tempPath = System.getProperty("java.io.tmpdir"); saveFile = new File(tempPath + File.separator + fileUploadFileName); FileUtils.copyFile(fileUpload, saveFile); EmailUtility.sendEmail(host, port, userName, password, recipient, subject, message, saveFile); if (saveFile != null) { saveFile.delete(); } return "success"; } public String getHost() { return host; } public void setHost(String host) { this.host = host; } public String getPort() { return port; } public void setPort(String port) { this.port = port; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public File getFileUpload() { return fileUpload; } public void setFileUpload(File fileUpload) { this.fileUpload = fileUpload; } public String getFileUploadFileName() { return fileUploadFileName; } public void setFileUploadFileName(String fileUploadFileName) { this.fileUploadFileName = fileUploadFileName; } public String getFileUploadContentType() { return fileUploadContentType; } public void setFileUploadContentType(String fileUploadContentType) { this.fileUploadContentType = fileUploadContentType; } public String getRecipient() { return recipient; } public void setRecipient(String recipient) { this.recipient = recipient; } public String getSubject() { return subject; } public void setSubject(String subject) { this.subject = subject; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }
In this action class, we declared JavaBean-style properties for:
The action method doSendEmail() will be invoked when the user hits submit button on the e-mail form. In this method, we copy the upload file to a temporary location; invoke the EmailUtility class for sending the e-mail; delete the temporary file and finally, return name of a success view (which is mapped to the result page).
Beside the EmailForm.jsp file, we have to create two other JSP files: Result.jsp and Error.jsp.
Write code for the Result.jsp page as follows:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Send Email Result</title> </head> <body> <center> <h2>The email was sent successfully!</h2> </center> </body> </html>
This result page will be displayed in case the e-mail was sent successfully.
And for the Error.jsp page as follows:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="s" uri="/struts-tags" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Send Email Error</title> </head> <body> <center> <h2>There were a problem while sending an e-mail to: <s:property value="recipient"/></h2> <h3>Error details:</h3> <h4><s:property value="exception" /></h4> </center> </body> </html>
This error page is only displayed in case an error occurred.
Create Struts configuration file called struts.xml with the following XML code:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <constant name="struts.multipart.maxSize" value="10485760" /> <!-- 10 MB --> <package name="Struts2Email" extends="struts-default"> <global-results> <result name="error">/Error.jsp</result> </global-results> <global-exception-mappings> <exception-mapping exception="java.lang.Exception" result="error" /> </global-exception-mappings> <action name="doSendEmail" class="net.codejava.struts2.SendEmailAction" method="sendEmail"> <!-- SMTP configuration --> <param name="host">smtp.gmail.com</param> <param name="port">587</param> <param name="userName">youremail</param> <param name="password">yourpassword</param> <!-- End of SMTP configuration --> <interceptor-ref name="fileUpload"> <param name="allowedTypes">*/*</param> <!-- all file types --> <param name="maximumSize">4194304</param> <!-- 4 MB --> </interceptor-ref> <interceptor-ref name="staticParams"/> <interceptor-ref name="params"/> <interceptor-ref name="validation" /> <interceptor-ref name="workflow" /> <interceptor-ref name="exception"/> <result name="success" type="redirect">/Result.jsp</result> <result name="input">/EmailForm.jsp</result> </action> </package> </struts>
Firstly, we restrict size of a multipart request up to 10MB at the beginning of the configuration.
Secondly, we configure exception mapping of exception type java.lang.Exception to a view named error (which maps to the error page).
In the action configuration, we declare a Struts action with the following attributes:
Inside <action> tag we declare:
Configure the web deployment descriptor file as follows:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>Struts2EmailApp</display-name> <welcome-file-list> <welcome-file>EmailForm.jsp</welcome-file> </welcome-file-list> <filter> <filter-name>struts2</filter-name> <filter-class> org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter </filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
This configuration simply declares the Struts dispatcher filter to intercept all requests coming to the application, and declares the EmailForm.jsp as the default page when accessing the application.
Deploy the application on Tomcat and type the following URL into web browser’s address bar:
http://localhost:8080/Struts2EmailApp
The e-mail form appears, enter required information and pick up a file to attach to the e-mail, for example:
If everything went well, a successful message appears:
In case an exception is thrown (such as invalid username/password of the SMTP settings), the error page will show up: