📄 htmlemail.java
字号:
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.apache.commons.mail;import java.io.File;import java.io.IOException;import java.io.InputStream;import java.net.MalformedURLException;import java.net.URL;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import javax.activation.DataHandler;import javax.activation.DataSource;import javax.activation.FileDataSource;import javax.activation.URLDataSource;import javax.mail.BodyPart;import javax.mail.MessagingException;import javax.mail.internet.MimeBodyPart;import javax.mail.internet.MimeMultipart;/** * An HTML multipart email. * * <p>This class is used to send HTML formatted email. A text message * can also be set for HTML unaware email clients, such as text-based * email clients. * * <p>This class also inherits from {@link MultiPartEmail}, so it is easy to * add attachments to the email. * * <p>To send an email in HTML, one should create a <code>HtmlEmail</code>, then * use the {@link #setFrom(String)}, {@link #addTo(String)} etc. methods. * The HTML content can be set with the {@link #setHtmlMsg(String)} method. The * alternative text content can be set with {@link #setTextMsg(String)}. * * <p>Either the text or HTML can be omitted, in which case the "main" * part of the multipart becomes whichever is supplied rather than a * <code>multipart/alternative</code>. * * <h3>Embedding Images and Media</h3> * * <p>It is also possible to embed URLs, files, or arbitrary * <code>DataSource</code>s directly into the body of the mail: * <pre><code> * HtmlEmail he = new HtmlEmail(); * File img = new File("my/image.gif"); * PNGDataSource png = new PNGDataSource(decodedPNGOutputStream); // a custom class * StringBuffer msg = new StringBuffer(); * msg.append("<html><body>"); * msg.append("<img src=cid:").append(he.embed(img)).append(">"); * msg.append("<img src=cid:").append(he.embed(png)).append(">"); * msg.append("</body></html>"); * he.setHtmlMsg(msg.toString()); * // code to set the other email fields (not shown) * </pre></code> * * <p>Embedded entities are tracked by their name, which for <code>File</code>s is * the filename itself and for <code>URL</code>s is the canonical path. It is * an error to bind the same name to more than one entity, and this class will * attempt to validate that for <code>File</code>s and <code>URL</code>s. When * embedding a <code>DataSource</code>, the code uses the <code>equals()</code> * method defined on the <code>DataSource</code>s to make the determination. * * @since 1.0 * @author <a href="mailto:unknown">Regis Koenig</a> * @author <a href="mailto:sean@informage.net">Sean Legassick</a> * @version $Id: HtmlEmail.java 578501 2007-09-22 21:18:49Z bspeakmon $ */public class HtmlEmail extends MultiPartEmail{ /** Definition of the length of generated CID's */ public static final int CID_LENGTH = 10; /** prefix for default HTML mail */ private static final String HTML_MESSAGE_START = "<html><body><pre>"; /** suffix for default HTML mail */ private static final String HTML_MESSAGE_END = "</pre></body></html>"; /** * Text part of the message. This will be used as alternative text if * the email client does not support HTML messages. */ protected String text; /** Html part of the message */ protected String html; /** * @deprecated As of commons-email 1.1, no longer used. Inline embedded * objects are now stored in {@link #inlineEmbeds}. */ protected List inlineImages; /** * Embedded images Map<String, InlineImage> where the key is the * user-defined image name. */ protected Map inlineEmbeds = new HashMap(); /** * Set the text content. * * @param aText A String. * @return An HtmlEmail. * @throws EmailException see javax.mail.internet.MimeBodyPart * for definitions * @since 1.0 */ public HtmlEmail setTextMsg(String aText) throws EmailException { if (EmailUtils.isEmpty(aText)) { throw new EmailException("Invalid message supplied"); } this.text = aText; return this; } /** * Set the HTML content. * * @param aHtml A String. * @return An HtmlEmail. * @throws EmailException see javax.mail.internet.MimeBodyPart * for definitions * @since 1.0 */ public HtmlEmail setHtmlMsg(String aHtml) throws EmailException { if (EmailUtils.isEmpty(aHtml)) { throw new EmailException("Invalid message supplied"); } this.html = aHtml; return this; } /** * Set the message. * * <p>This method overrides {@link MultiPartEmail#setMsg(String)} in * order to send an HTML message instead of a plain text message in * the mail body. The message is formatted in HTML for the HTML * part of the message; it is left as is in the alternate text * part. * * @param msg the message text to use * @return this <code>HtmlEmail</code> * @throws EmailException if msg is null or empty; * see javax.mail.internet.MimeBodyPart for definitions * @since 1.0 */ public Email setMsg(String msg) throws EmailException { if (EmailUtils.isEmpty(msg)) { throw new EmailException("Invalid message supplied"); } setTextMsg(msg); StringBuffer htmlMsgBuf = new StringBuffer( msg.length() + HTML_MESSAGE_START.length() + HTML_MESSAGE_END.length() ); htmlMsgBuf.append(HTML_MESSAGE_START) .append(msg) .append(HTML_MESSAGE_END); setHtmlMsg(htmlMsgBuf.toString()); return this; } /** * Attempts to parse the specified <code>String</code> as a URL that will * then be embedded in the message. * * @param urlString String representation of the URL. * @param name The name that will be set in the filename header field. * @return A String with the Content-ID of the URL. * @throws EmailException when URL supplied is invalid or if <code> is null * or empty; also see {@link javax.mail.internet.MimeBodyPart} for definitions * * @see #embed(URL, String) * @since 1.1 */ public String embed(String urlString, String name) throws EmailException { try { return embed(new URL(urlString), name); } catch (MalformedURLException e) { throw new EmailException("Invalid URL", e); } } /** * Embeds an URL in the HTML. * * <p>This method embeds a file located by an URL into * the mail body. It allows, for instance, to add inline images * to the email. Inline files may be referenced with a * <code>cid:xxxxxx</code> URL, where xxxxxx is the Content-ID * returned by the embed function. It is an error to bind the same name * to more than one URL; if the same URL is embedded multiple times, the * same Content-ID is guaranteed to be returned. * * <p>While functionally the same as passing <code>URLDataSource</code> to * {@link #embed(DataSource, String, String)}, this method attempts * to validate the URL before embedding it in the message and will throw * <code>EmailException</code> if the validation fails. In this case, the * <code>HtmlEmail</code> object will not be changed. * * <p> * NOTE: Clients should take care to ensure that different URLs are bound to * different names. This implementation tries to detect this and throw * <code>EmailException</code>. However, it is not guaranteed to catch * all cases, especially when the URL refers to a remote HTTP host that * may be part of a virtual host cluster. * * @param url The URL of the file. * @param name The name that will be set in the filename header * field. * @return A String with the Content-ID of the file. * @throws EmailException when URL supplied is invalid or if <code> is null * or empty; also see {@link javax.mail.internet.MimeBodyPart} for definitions * @since 1.0 */ public String embed(URL url, String name) throws EmailException { if (EmailUtils.isEmpty(name)) { throw new EmailException("name cannot be null or empty"); } // check if a URLDataSource for this name has already been attached; // if so, return the cached CID value. if (inlineEmbeds.containsKey(name)) { InlineImage ii = (InlineImage) inlineEmbeds.get(name); URLDataSource urlDataSource = (URLDataSource) ii.getDataSource(); // make sure the supplied URL points to the same thing // as the one already associated with this name. if (url.equals(urlDataSource.getURL())) { return ii.getCid(); } else { throw new EmailException("embedded name '" + name + "' is already bound to URL " + urlDataSource.getURL() + "; existing names cannot be rebound"); } // NOTE: Comparing URLs with URL.equals() is known to be // inconsistent when dealing with virtual hosting over HTTP, // but since these are almost always files on the local machine, // using equals() should be sufficient. } // verify that the URL is valid InputStream is = null; try { is = url.openStream(); } catch (IOException e) { throw new EmailException("Invalid URL", e); } finally { try { if (is != null) { is.close(); } } catch (IOException ioe) { /* sigh */ } } return embed(new URLDataSource(url), name); } /** * Embeds a file in the HTML. This implementation delegates to * {@link #embed(File, String)}. * * @param file The <code>File</code> object to embed * @return A String with the Content-ID of the file. * @throws EmailException when the supplied <code>File</code> cannot be * used; also see {@link javax.mail.internet.MimeBodyPart} for definitions * * @see #embed(File, String) * @since 1.1 */ public String embed(File file) throws EmailException { String cid = EmailUtils.randomAlphabetic(HtmlEmail.CID_LENGTH).toLowerCase(); return embed(file, cid); } /** * Embeds a file in the HTML. * * <p>This method embeds a file located by an URL into * the mail body. It allows, for instance, to add inline images * to the email. Inline files may be referenced with a * <code>cid:xxxxxx</code> URL, where xxxxxx is the Content-ID * returned by the embed function. Files are bound to their names, which is * the value returned by {@link java.io.File#getName()}. If the same file * is embedded multiple times, the same CID is guaranteed to be returned. * * <p>While functionally the same as passing <code>FileDataSource</code> to * {@link #embed(DataSource, String, String)}, this method attempts * to validate the file before embedding it in the message and will throw * <code>EmailException</code> if the validation fails. In this case, the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -