Browse Source

MimeMessageHelper encodes attachment filename if not ASCII compliant

Issue: SPR-9258
3.1.x
Juergen Hoeller 13 years ago
parent
commit
bad2b900e9
  1. 74
      org.springframework.context.support/src/main/java/org/springframework/mail/javamail/MimeMessageHelper.java

74
org.springframework.context.support/src/main/java/org/springframework/mail/javamail/MimeMessageHelper.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -35,6 +35,7 @@ import javax.mail.internet.MimeBodyPart; @@ -35,6 +35,7 @@ import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimePart;
import javax.mail.internet.MimeUtility;
import org.springframework.core.io.InputStreamSource;
import org.springframework.core.io.Resource;
@ -355,7 +356,7 @@ public class MimeMessageHelper { @@ -355,7 +356,7 @@ public class MimeMessageHelper {
/**
* Set the given MimeMultipart objects for use by this MimeMessageHelper.
* @param root the root MimeMultipart object, which attachments will be added to;
* or <code>null</code> to indicate no multipart at all
* or {@code null} to indicate no multipart at all
* @param main the main MimeMultipart object, which text(s) and inline elements
* will be added to (can be the same as the root multipart object, or an element
* nested underneath the root multipart element)
@ -420,7 +421,7 @@ public class MimeMessageHelper { @@ -420,7 +421,7 @@ public class MimeMessageHelper {
* Determine the default encoding for the given MimeMessage.
* @param mimeMessage the passed-in MimeMessage
* @return the default encoding associated with the MimeMessage,
* or <code>null</code> if none found
* or {@code null} if none found
*/
protected String getDefaultEncoding(MimeMessage mimeMessage) {
if (mimeMessage instanceof SmartMimeMessage) {
@ -456,12 +457,12 @@ public class MimeMessageHelper { @@ -456,12 +457,12 @@ public class MimeMessageHelper {
}
/**
* Set the Java Activation Framework <code>FileTypeMap</code> to use
* Set the Java Activation Framework {@code FileTypeMap} to use
* for determining the content type of inline content and attachments
* that get added to the message.
* <p>Default is the <code>FileTypeMap</code> that the underlying
* <p>Default is the {@code FileTypeMap} that the underlying
* MimeMessage carries, if any, or the Activation Framework's default
* <code>FileTypeMap</code> instance else.
* {@code FileTypeMap} instance else.
* @see #addInline
* @see #addAttachment
* @see #getDefaultFileTypeMap(javax.mail.internet.MimeMessage)
@ -474,7 +475,7 @@ public class MimeMessageHelper { @@ -474,7 +475,7 @@ public class MimeMessageHelper {
}
/**
* Return the <code>FileTypeMap</code> used by this MimeMessageHelper.
* Return the {@code FileTypeMap} used by this MimeMessageHelper.
*/
public FileTypeMap getFileTypeMap() {
return this.fileTypeMap;
@ -485,7 +486,7 @@ public class MimeMessageHelper { @@ -485,7 +486,7 @@ public class MimeMessageHelper {
* Set whether to validate all addresses which get passed to this helper.
* Default is "false".
* <p>Note that this is by default just available for JavaMail >= 1.3.
* You can override the default <code>validateAddress method</code> for
* You can override the default {@code validateAddress method} for
* validation on older JavaMail versions (or for custom validation).
* @see #validateAddress
*/
@ -503,7 +504,7 @@ public class MimeMessageHelper { @@ -503,7 +504,7 @@ public class MimeMessageHelper {
/**
* Validate the given mail address.
* Called by all of MimeMessageHelper's address setters and adders.
* <p>Default implementation invokes <code>InternetAddress.validate()</code>,
* <p>Default implementation invokes {@code InternetAddress.validate()},
* provided that address validation is activated for the helper instance.
* <p>Note that this method will just work on JavaMail >= 1.3. You can override
* it for validation on older JavaMail versions or for custom validation.
@ -730,7 +731,7 @@ public class MimeMessageHelper { @@ -730,7 +731,7 @@ public class MimeMessageHelper {
/**
* Set the sent-date of the message.
* @param sentDate the date to set (never <code>null</code>)
* @param sentDate the date to set (never {@code null})
* @throws MessagingException in case of errors
*/
public void setSentDate(Date sentDate) throws MessagingException {
@ -758,7 +759,7 @@ public class MimeMessageHelper { @@ -758,7 +759,7 @@ public class MimeMessageHelper {
* Set the given text directly as content in non-multipart mode
* or as default body part in multipart mode.
* Always applies the default content type "text/plain".
* <p><b>NOTE:</b> Invoke {@link #addInline} <i>after</i> <code>setText</code>;
* <p><b>NOTE:</b> Invoke {@link #addInline} <i>after</i> {@code setText};
* else, mail readers might not be able to resolve inline references correctly.
* @param text the text for the message
* @throws MessagingException in case of errors
@ -771,7 +772,7 @@ public class MimeMessageHelper { @@ -771,7 +772,7 @@ public class MimeMessageHelper {
* Set the given text directly as content in non-multipart mode
* or as default body part in multipart mode.
* The "html" flag determines the content type to apply.
* <p><b>NOTE:</b> Invoke {@link #addInline} <i>after</i> <code>setText</code>;
* <p><b>NOTE:</b> Invoke {@link #addInline} <i>after</i> {@code setText};
* else, mail readers might not be able to resolve inline references correctly.
* @param text the text for the message
* @param html whether to apply content type "text/html" for an
@ -798,7 +799,7 @@ public class MimeMessageHelper { @@ -798,7 +799,7 @@ public class MimeMessageHelper {
/**
* Set the given plain text and HTML text as alternatives, offering
* both options to the email client. Requires multipart mode.
* <p><b>NOTE:</b> Invoke {@link #addInline} <i>after</i> <code>setText</code>;
* <p><b>NOTE:</b> Invoke {@link #addInline} <i>after</i> {@code setText};
* else, mail readers might not be able to resolve inline references correctly.
* @param plainText the plain text for the message
* @param htmlText the HTML text for the message
@ -860,16 +861,16 @@ public class MimeMessageHelper { @@ -860,16 +861,16 @@ public class MimeMessageHelper {
/**
* Add an inline element to the MimeMessage, taking the content from a
* <code>javax.activation.DataSource</code>.
* {@code javax.activation.DataSource}.
* <p>Note that the InputStream returned by the DataSource implementation
* needs to be a <i>fresh one on each call</i>, as JavaMail will invoke
* <code>getInputStream()</code> multiple times.
* <p><b>NOTE:</b> Invoke <code>addInline</code> <i>after</i> {@link #setText};
* {@code getInputStream()} multiple times.
* <p><b>NOTE:</b> Invoke {@code addInline} <i>after</i> {@link #setText};
* else, mail readers might not be able to resolve inline references correctly.
* @param contentId the content ID to use. Will end up as "Content-ID" header
* in the body part, surrounded by angle brackets: e.g. "myId" -> "&lt;myId&gt;".
* Can be referenced in HTML source via src="cid:myId" expressions.
* @param dataSource the <code>javax.activation.DataSource</code> to take
* @param dataSource the {@code javax.activation.DataSource} to take
* the content from, determining the InputStream and the content type
* @throws MessagingException in case of errors
* @see #addInline(String, java.io.File)
@ -889,11 +890,11 @@ public class MimeMessageHelper { @@ -889,11 +890,11 @@ public class MimeMessageHelper {
/**
* Add an inline element to the MimeMessage, taking the content from a
* <code>java.io.File</code>.
* {@code java.io.File}.
* <p>The content type will be determined by the name of the given
* content file. Do not use this for temporary files with arbitrary
* filenames (possibly ending in ".tmp" or the like)!
* <p><b>NOTE:</b> Invoke <code>addInline</code> <i>after</i> {@link #setText};
* <p><b>NOTE:</b> Invoke {@code addInline} <i>after</i> {@link #setText};
* else, mail readers might not be able to resolve inline references correctly.
* @param contentId the content ID to use. Will end up as "Content-ID" header
* in the body part, surrounded by angle brackets: e.g. "myId" -> "&lt;myId&gt;".
@ -913,14 +914,14 @@ public class MimeMessageHelper { @@ -913,14 +914,14 @@ public class MimeMessageHelper {
/**
* Add an inline element to the MimeMessage, taking the content from a
* <code>org.springframework.core.io.Resource</code>.
* {@code org.springframework.core.io.Resource}.
* <p>The content type will be determined by the name of the given
* content file. Do not use this for temporary files with arbitrary
* filenames (possibly ending in ".tmp" or the like)!
* <p>Note that the InputStream returned by the Resource implementation
* needs to be a <i>fresh one on each call</i>, as JavaMail will invoke
* <code>getInputStream()</code> multiple times.
* <p><b>NOTE:</b> Invoke <code>addInline</code> <i>after</i> {@link #setText};
* {@code getInputStream()} multiple times.
* <p><b>NOTE:</b> Invoke {@code addInline} <i>after</i> {@link #setText};
* else, mail readers might not be able to resolve inline references correctly.
* @param contentId the content ID to use. Will end up as "Content-ID" header
* in the body part, surrounded by angle brackets: e.g. "myId" -> "&lt;myId&gt;".
@ -939,14 +940,14 @@ public class MimeMessageHelper { @@ -939,14 +940,14 @@ public class MimeMessageHelper {
/**
* Add an inline element to the MimeMessage, taking the content from an
* <code>org.springframework.core.InputStreamResource</code>, and
* {@code org.springframework.core.InputStreamResource}, and
* specifying the content type explicitly.
* <p>You can determine the content type for any given filename via a Java
* Activation Framework's FileTypeMap, for example the one held by this helper.
* <p>Note that the InputStream returned by the InputStreamSource implementation
* needs to be a <i>fresh one on each call</i>, as JavaMail will invoke
* <code>getInputStream()</code> multiple times.
* <p><b>NOTE:</b> Invoke <code>addInline</code> <i>after</i> <code>setText</code>;
* {@code getInputStream()} multiple times.
* <p><b>NOTE:</b> Invoke {@code addInline} <i>after</i> {@code setText};
* else, mail readers might not be able to resolve inline references correctly.
* @param contentId the content ID to use. Will end up as "Content-ID" header
* in the body part, surrounded by angle brackets: e.g. "myId" -> "&lt;myId&gt;".
@ -974,13 +975,13 @@ public class MimeMessageHelper { @@ -974,13 +975,13 @@ public class MimeMessageHelper {
/**
* Add an attachment to the MimeMessage, taking the content from a
* <code>javax.activation.DataSource</code>.
* {@code javax.activation.DataSource}.
* <p>Note that the InputStream returned by the DataSource implementation
* needs to be a <i>fresh one on each call</i>, as JavaMail will invoke
* <code>getInputStream()</code> multiple times.
* {@code getInputStream()} multiple times.
* @param attachmentFilename the name of the attachment as it will
* appear in the mail (the content type will be determined by this)
* @param dataSource the <code>javax.activation.DataSource</code> to take
* @param dataSource the {@code javax.activation.DataSource} to take
* the content from, determining the InputStream and the content type
* @throws MessagingException in case of errors
* @see #addAttachment(String, org.springframework.core.io.InputStreamSource)
@ -989,16 +990,21 @@ public class MimeMessageHelper { @@ -989,16 +990,21 @@ public class MimeMessageHelper {
public void addAttachment(String attachmentFilename, DataSource dataSource) throws MessagingException {
Assert.notNull(attachmentFilename, "Attachment filename must not be null");
Assert.notNull(dataSource, "DataSource must not be null");
try {
MimeBodyPart mimeBodyPart = new MimeBodyPart();
mimeBodyPart.setDisposition(MimeBodyPart.ATTACHMENT);
mimeBodyPart.setFileName(attachmentFilename);
mimeBodyPart.setFileName(MimeUtility.encodeText(attachmentFilename));
mimeBodyPart.setDataHandler(new DataHandler(dataSource));
getRootMimeMultipart().addBodyPart(mimeBodyPart);
}
catch (UnsupportedEncodingException ex) {
throw new MessagingException("Failed to encode attachment filename", ex);
}
}
/**
* Add an attachment to the MimeMessage, taking the content from a
* <code>java.io.File</code>.
* {@code java.io.File}.
* <p>The content type will be determined by the name of the given
* content file. Do not use this for temporary files with arbitrary
* filenames (possibly ending in ".tmp" or the like)!
@ -1018,13 +1024,13 @@ public class MimeMessageHelper { @@ -1018,13 +1024,13 @@ public class MimeMessageHelper {
/**
* Add an attachment to the MimeMessage, taking the content from an
* <code>org.springframework.core.io.InputStreamResource</code>.
* {@code org.springframework.core.io.InputStreamResource}.
* <p>The content type will be determined by the given filename for
* the attachment. Thus, any content source will be fine, including
* temporary files with arbitrary filenames.
* <p>Note that the InputStream returned by the InputStreamSource
* implementation needs to be a <i>fresh one on each call</i>, as
* JavaMail will invoke <code>getInputStream()</code> multiple times.
* JavaMail will invoke {@code getInputStream()} multiple times.
* @param attachmentFilename the name of the attachment as it will
* appear in the mail
* @param inputStreamSource the resource to take the content from
@ -1043,10 +1049,10 @@ public class MimeMessageHelper { @@ -1043,10 +1049,10 @@ public class MimeMessageHelper {
/**
* Add an attachment to the MimeMessage, taking the content from an
* <code>org.springframework.core.io.InputStreamResource</code>.
* {@code org.springframework.core.io.InputStreamResource}.
* <p>Note that the InputStream returned by the InputStreamSource
* implementation needs to be a <i>fresh one on each call</i>, as
* JavaMail will invoke <code>getInputStream()</code> multiple times.
* JavaMail will invoke {@code getInputStream()} multiple times.
* @param attachmentFilename the name of the attachment as it will
* appear in the mail
* @param inputStreamSource the resource to take the content from

Loading…
Cancel
Save