/* * Copyright (c) 1998-2011 Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Oracle nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ import java.io.*; import java.util.*; import java.text.*; import javax.servlet.*; import javax.servlet.http.*; import javax.mail.*; import javax.mail.Part; import javax.mail.internet.*; import javax.activation.*; /** * This is a servlet that demonstrates the use of JavaMail APIs * in a 3-tier application. It allows the user to login to an * IMAP store, list all the messages in the INBOX folder, view * selected messages, compose and send a message, and logout. *

* Please note: This is NOT an example of how to write servlets! * This is simply to show that JavaMail can be used in a servlet. *

* For more information on this servlet, see the * JavaMailServlet.README.txt file. *

* For more information on servlets, see * * http://java.sun.com/products/java-server/servlets/index.html * * @author Max Spivak */ public class JavaMailServlet extends HttpServlet implements SingleThreadModel { String protocol = "imap"; String mbox = "INBOX"; /** * This method handles the "POST" submission from two forms: the * login form and the message compose form. The login form has the * following parameters: hostname, username, * and password. The send parameter denotes * that the method is processing the compose form submission. */ public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { // get the session HttpSession ssn = req.getSession(true); String send = req.getParameter("send"); String host = req.getParameter("hostname"); String user = req.getParameter("username"); String passwd = req.getParameter("password"); URLName url = new URLName(protocol, host, -1, mbox, user, passwd); ServletOutputStream out = res.getOutputStream(); res.setContentType("text/html"); out.println(""); if (send != null) { // process message sending send(req, res, out, ssn); } else { // initial login // create MailUserData mud = new MailUserData(url); ssn.putValue("javamailservlet", mud); try { Properties props = System.getProperties(); props.put("mail.smtp.host", host); Session session = Session.getDefaultInstance(props, null); session.setDebug(false); Store store = session.getStore(url); store.connect(); Folder folder = store.getDefaultFolder(); if (folder == null) throw new MessagingException("No default folder"); folder = folder.getFolder(mbox); if (folder == null) throw new MessagingException("Invalid folder"); folder.open(Folder.READ_WRITE); int totalMessages = folder.getMessageCount(); Message[] msgs = folder.getMessages(); FetchProfile fp = new FetchProfile(); fp.add(FetchProfile.Item.ENVELOPE); folder.fetch(msgs, fp); // track who logged in System.out.println("Login from: " + store.getURLName()); // save stuff into MUD mud.setSession(session); mud.setStore(store); mud.setFolder(folder); // splash out.print("

"); out.print(""); out.println("Welcome to JavaMail!

"); // folder table out.println(""); // folder name column header out.print("
"); // msg count column header out.print("
"); out.println(""); // folder name out.print("
"); // msg count out.println(""); out.println(""); out.println(""); out.close(); } } } /** * This method handles the GET requests for the client. */ public void doGet (HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { HttpSession ses = req.getSession(false); // before we write to out ServletOutputStream out = res.getOutputStream(); MailUserData mud = getMUD(ses); if (mud == null) { res.setContentType("text/html"); out.println("Please Login (no session)"); out.close(); return; } if (!mud.getStore().isConnected()) { res.setContentType("text/html"); out.println("Not Connected To Store"); out.close(); return; } // mux that takes a GET request, based on parameters figures // out what it should do, and routes it to the // appropriate method // get url parameters String msgStr = req.getParameter("message"); String logout = req.getParameter("logout"); String compose = req.getParameter("compose"); String part = req.getParameter("part"); int msgNum = -1; int partNum = -1; // process url params if (msgStr != null) { // operate on message "msgStr" msgNum = Integer.parseInt(msgStr); if (part == null) { // display message "msgStr" res.setContentType("text/html"); displayMessage(mud, req, out, msgNum); } else { // display part "part" in message "msgStr" partNum = Integer.parseInt(part); displayPart(mud, msgNum, partNum, out, res); } } else if (compose != null) { // display compose form compose(mud, res, out); } else if (logout != null) { // process logout try { mud.getFolder().close(false); mud.getStore().close(); ses.invalidate(); out.println("Logged out OK"); } catch (MessagingException mex) { out.println(mex.toString()); } } else { // display headers displayHeaders(mud, req, out); } } /* main method to display messages */ private void displayMessage(MailUserData mud, HttpServletRequest req, ServletOutputStream out, int msgNum) throws IOException { out.println(""); out.println("JavaMail Servlet"); out.println(""); out.print("
"); out.println("Message " + (msgNum+1) + " in folder " + mud.getStore().getURLName() + "/INBOX

"); try { Message msg = mud.getFolder().getMessage(msgNum); // first, display this message's headers displayMessageHeaders(mud, msg, out); // and now, handle the content Object o = msg.getContent(); //if (o instanceof String) { if (msg.isMimeType("text/plain")) { out.println("

");
		out.println((String)o);
		out.println("
"); //} else if (o instanceof Multipart){ } else if (msg.isMimeType("multipart/*")) { Multipart mp = (Multipart)o; int cnt = mp.getCount(); for (int i = 0; i < cnt; i++) { displayPart(mud, msgNum, mp.getBodyPart(i), i, req, out); } } else { out.println(msg.getContentType()); } } catch (MessagingException mex) { out.println(mex.toString()); } out.println(""); out.close(); } /** * This method displays a message part. text/plain * content parts are displayed inline. For all other parts, * a URL is generated and displayed; clicking on the URL * brings up the part in a separate page. */ private void displayPart(MailUserData mud, int msgNum, Part part, int partNum, HttpServletRequest req, ServletOutputStream out) throws IOException { if (partNum != 0) out.println("


"); try { String sct = part.getContentType(); if (sct == null) { out.println("invalid part"); return; } ContentType ct = new ContentType(sct); if (partNum != 0) out.println("Attachment Type: " + ct.getBaseType() + "
"); if (ct.match("text/plain")) { // display text/plain inline out.println("
");
		out.println((String)part.getContent());
		out.println("
"); } else { // generate a url for this part String s; if ((s = part.getFileName()) != null) out.println("Filename: " + s + "
"); s = null; if ((s = part.getDescription()) != null) out.println("Description: " + s + "
"); out.println("Display Attachment"); } } catch (MessagingException mex) { out.println(mex.toString()); } } /** * This method gets the stream from for a given msg part and * pushes it out to the browser with the correct content type. * Used to display attachments and relies on the browser's * content handling capabilities. */ private void displayPart(MailUserData mud, int msgNum, int partNum, ServletOutputStream out, HttpServletResponse res) throws IOException { Part part = null; try { Message msg = mud.getFolder().getMessage(msgNum); Multipart mp = (Multipart)msg.getContent(); part = mp.getBodyPart(partNum); String sct = part.getContentType(); if (sct == null) { out.println("invalid part"); return; } ContentType ct = new ContentType(sct); res.setContentType(ct.getBaseType()); InputStream is = part.getInputStream(); int i; while ((i = is.read()) != -1) out.write(i); out.flush(); out.close(); } catch (MessagingException mex) { out.println(mex.toString()); } } /** * This is a utility message that pretty-prints the message * headers for message that is being displayed. */ private void displayMessageHeaders(MailUserData mud, Message msg, ServletOutputStream out) throws IOException { try { out.println("Date: " + msg.getSentDate() + "
"); Address[] fr = msg.getFrom(); if (fr != null) { boolean tf = true; out.print("From: "); for (int i = 0; i < fr.length; i++) { out.print(((tf) ? " " : ", ") + getDisplayAddress(fr[i])); tf = false; } out.println("
"); } Address[] to = msg.getRecipients(Message.RecipientType.TO); if (to != null) { boolean tf = true; out.print("To: "); for (int i = 0; i < to.length; i++) { out.print(((tf) ? " " : ", ") + getDisplayAddress(to[i])); tf = false; } out.println("
"); } Address[] cc = msg.getRecipients(Message.RecipientType.CC); if (cc != null) { boolean cf = true; out.print("CC: "); for (int i = 0; i < cc.length; i++) { out.print(((cf) ? " " : ", ") + getDisplayAddress(cc[i])); cf = false; } out.println("
"); } out.print("Subject: " + ((msg.getSubject() !=null) ? msg.getSubject() : "") + "
"); } catch (MessagingException mex) { out.println(msg.toString()); } } /** * This method displays the URL's for the available commands and the * INBOX headerlist */ private void displayHeaders(MailUserData mud, HttpServletRequest req, ServletOutputStream out) throws IOException { SimpleDateFormat df = new SimpleDateFormat("EE M/d/yy"); out.println(""); out.println("JavaMail Servlet"); out.println("
"); out.print("
"); out.println("Folder " + mud.getStore().getURLName() + "/INBOX

"); // URL's for the commands that are available out.println(""); out.println("Logout"); out.println("Compose"); out.println(""); out.println("


"); // List headers in a table out.print("
"); out.print(""); out.println("FolderName"); out.print(""); out.println("Messages
"); out.print("" + "Inbox" + "" + totalMessages + "
"); // settings // sender column header out.println(""); // date column header out.println(""); // subject column header out.println(""); try { Folder f = mud.getFolder(); int msgCount = f.getMessageCount(); Message m = null; // for each message, show its headers for (int i = 1; i <= msgCount; i++) { m = f.getMessage(i); // if message has the DELETED flag set, don't display it if (m.isSet(Flags.Flag.DELETED)) continue; // from out.println(""); out.print(""); // date out.print(""); // subject & link out.print(""); out.println(""); } } catch (MessagingException mex) { out.println(""); mex.printStackTrace(); } out.println("
"); out.println(""); out.println("Sender"); out.println(""); out.println("Date"); out.println(""); out.println("Subject
"); out.println("" + ((m.getFrom() != null) ? m.getFrom()[0].toString() : "" ) + ""); out.println("" + df.format((m.getSentDate()!=null) ? m.getSentDate() : m.getReceivedDate()) + ""); out.println("" + "" + ((m.getSubject() != null) ? m.getSubject() : "No Subject") + "" + "
" + mex.toString() + "
"); out.println(""); out.flush(); out.close(); } /** * This method handles the request when the user hits the * Compose link. It send the compose form to the browser. */ private void compose(MailUserData mud, HttpServletResponse res, ServletOutputStream out) throws IOException { res.setContentType("text/html"); out.println(composeForm); out.close(); } /** * This method processes the send request from the compose form */ private void send(HttpServletRequest req, HttpServletResponse res, ServletOutputStream out, HttpSession ssn) throws IOException { String to = req.getParameter("to"); String cc = req.getParameter("cc"); String subj = req.getParameter("subject"); String text = req.getParameter("text"); try { MailUserData mud = getMUD(ssn); if (mud == null) throw new Exception("trying to send, but not logged in"); Message msg = new MimeMessage(mud.getSession()); InternetAddress[] toAddrs = null, ccAddrs = null; if (to != null) { toAddrs = InternetAddress.parse(to, false); msg.setRecipients(Message.RecipientType.TO, toAddrs); } else throw new MessagingException("No \"To\" address specified"); if (cc != null) { ccAddrs = InternetAddress.parse(cc, false); msg.setRecipients(Message.RecipientType.CC, ccAddrs); } if (subj != null) msg.setSubject(subj); URLName u = mud.getURLName(); msg.setFrom(new InternetAddress(u.getUsername() + "@" + u.getHost())); if (text != null) msg.setText(text); Transport.send(msg); out.println("

Message sent successfully

"); out.close(); } catch (Exception mex) { out.println("

Error sending message.

"); out.println(mex.toString()); out.println("
"); } } // utility method; returns a string suitable for msg header display private String getDisplayAddress(Address a) { String pers = null; String addr = null; if (a instanceof InternetAddress && ((pers = ((InternetAddress)a).getPersonal()) != null)) { addr = pers + " "+"<"+((InternetAddress)a).getAddress()+">"; } else addr = a.toString(); return addr; } // utility method; retrieve the MailUserData // from the HttpSession and return it private MailUserData getMUD(HttpSession ses) throws IOException { MailUserData mud = null; if (ses == null) { return null; } else { if ((mud = (MailUserData)ses.getValue("javamailservlet")) == null){ return null; } } return mud; } public String getServletInfo() { return "A mail reader servlet"; } /** * This is the HTML code for the compose form. Another option would * have been to use a separate html page. */ private static String composeForm = "JavaMail Compose

JavaMail Compose Message

To:

(separate addresses with commas)

CC:

(separate addresses with commas)

Subject:

 
 

"; } /** * This class is used to store session data for each user's session. It * is stored in the HttpSession. */ class MailUserData { URLName url; Session session; Store store; Folder folder; public MailUserData(URLName urlname) { url = urlname; } public URLName getURLName() { return url; } public Session getSession() { return session; } public void setSession(Session s) { session = s; } public Store getStore() { return store; } public void setStore(Store s) { store = s; } public Folder getFolder() { return folder; } public void setFolder(Folder f) { folder = f; } }