1 .依赖库
mail.jar
2. 代码
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.mail.MessagingException;
import javax.mail.Part;
import javax.mail.Session;
import javax.mail.internet.ContentType;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;
import javax.mail.internet.ParseException;
import javax.mail.internet.PreencodedMimeBodyPart;
import org.apache.log4j.Logger;
public class MimeEncoder {
private Logger logger = Logger.getLogger(MimeEncoder.class);
private String encoding = "UTF-8";
private String transferEncoding = "base64";
private String subtype = "mixed";
private MimeBodyPart txtContent;
private MimeBodyPart htmlContent;
private List<MimeBodyPart> inlineList = new ArrayList<MimeBodyPart>(); //内嵌文件
private List<MimeBodyPart> attachmentList = new ArrayList<MimeBodyPart>(); //附件
private Map<String, String> headers = new LinkedHashMap<String, String>();
public MimeEncoder(){
}
public MimeEncoder(String encoding){
this.encoding = encoding;
}
/**
* 构造MIME编码器
* @param encoding String MIME正文默认字符编码
* @param transferEncoding MIME段体传输编码("base64", "quoted-printable", "7bit", "8bit", "binary", "uuencode")
*/
public MimeEncoder(String encoding, String transferEncoding){
this.encoding = encoding;
this.transferEncoding = transferEncoding;
}
public void setSubType(String subtype){
this.subtype = subtype;
}
public void setHeader(String name, String value){
headers.put(name, value);
}
private String readFile(File f)throws IOException, MessagingException{
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(f));
String s = encodeInputStream(bis);
bis.close();
return s;
}
private String contentEnode(String contentText, String contentType)throws IOException, MessagingException{
String contentEncode = encoding;
if(contentType != null){
ContentType ct = new ContentType(contentType);
if(ct.getParameter("charset") != null){
contentEncode = ct.getParameter("charset");
}
}
return contentEnode(contentText.getBytes(contentEncode));
}
private String contentEnode(byte[] content)throws IOException, MessagingException{
ByteArrayInputStream bais = new ByteArrayInputStream(content);
String s = encodeInputStream(bais);
bais.close();
return s;
}
private String encodeInputStream(InputStream is)throws IOException, MessagingException{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os = MimeUtility.encode(baos, transferEncoding);
int data = -1;
while((data = is.read()) != -1){
os.write(data);
}
String s = baos.toString(encoding);
os.close();
baos.close();
return s;
}
public void setTxtContent(String content)throws ParseException{
ContentType ct = new ContentType("text/plain");
ct.setParameter("charset", encoding);
setTxtContent(content, ct.toString());
}
public void setTxtContent(String content, String contentType){
PreencodedMimeBodyPart txtContentPart = new PreencodedMimeBodyPart(transferEncoding);
try {
txtContentPart.setText(contentEnode(content, contentType));
if(contentType != null){
txtContentPart.setHeader("Content-Type", contentType);
}
this.txtContent = txtContentPart;
} catch (Exception e) {
logger.warn(e.getMessage(), e);
}
}
public void setHtmlContent(String content)throws ParseException{
ContentType ct = new ContentType("text/html");
ct.setParameter("charset", encoding);
setHtmlContent(content, ct.toString());
}
public void setHtmlContent(String content, String contentType){
PreencodedMimeBodyPart htmlContentPart = new PreencodedMimeBodyPart(transferEncoding);
try {
htmlContentPart.setText(contentEnode(content, contentType));
if(contentType != null){
htmlContentPart.setHeader("Content-Type", contentType);
}
this.htmlContent = htmlContentPart;
} catch (Exception e) {
logger.warn(e.getMessage(), e);
}
}
public void addAttachment(File f, String contentType){
PreencodedMimeBodyPart attachmentPart = new PreencodedMimeBodyPart(transferEncoding);
try {
attachmentPart.setText(readFile(f));
attachmentPart.setDisposition(Part.ATTACHMENT);
attachmentPart.setFileName(nameEncode(f.getName()));
if(contentType != null){
attachmentPart.setHeader("Content-Type", contentType);
}
attachmentList.add(attachmentPart);
} catch (Exception e) {
logger.warn(e.getMessage(), e);
}
}
public void addAttachment(String fileName, String contentText, String contentType){
PreencodedMimeBodyPart attachmentPart = new PreencodedMimeBodyPart(transferEncoding);
try {
attachmentPart.setText(contentEnode(contentText, contentType));
attachmentPart.setDisposition(Part.ATTACHMENT);
attachmentPart.setFileName(fileName);
if(contentType != null){
attachmentPart.setHeader("Content-Type", contentType);
}
attachmentList.add(attachmentPart);
} catch (Exception e) {
logger.warn(e.getMessage(), e);
e.printStackTrace();
}
}
public void addAttachment(String fileName, byte[] data, String contentType){
PreencodedMimeBodyPart attachmentPart = new PreencodedMimeBodyPart(transferEncoding);
try {
attachmentPart.setText(contentEnode(data));
attachmentPart.setDisposition(Part.ATTACHMENT);
attachmentPart.setFileName(fileName);
if(contentType != null){
attachmentPart.setHeader("Content-Type", contentType);
}
attachmentList.add(attachmentPart);
} catch (Exception e) {
logger.warn(e.getMessage(), e);
e.printStackTrace();
}
}
public void addInline(File f, String contentType){
addInline(f.getName(), f, contentType);
}
public void addInline(String name, File f, String contentType){
PreencodedMimeBodyPart inlinePart = new PreencodedMimeBodyPart(transferEncoding);
try {
inlinePart.setText(readFile(f));
inlinePart.setDisposition(Part.INLINE);
inlinePart.setContentID(nameEncode(name));
if(contentType != null){
inlinePart.setHeader("Content-Type", contentType);
}
inlineList.add(inlinePart);
} catch (Exception e) {
logger.warn(e.getMessage(), e);
}
}
public void addInline(String name, String contentText, String contentType){
PreencodedMimeBodyPart inlinePart = new PreencodedMimeBodyPart(transferEncoding);
try {
inlinePart.setText(contentEnode(contentText, contentType));
inlinePart.setDisposition(Part.INLINE);
inlinePart.setContentID(nameEncode(name));
if(contentType != null){
inlinePart.setHeader("Content-Type", contentType);
}
inlineList.add(inlinePart);
} catch (Exception e) {
logger.warn(e.getMessage(), e);
}
}
public void addInline(String name, byte[] data, String contentType){
PreencodedMimeBodyPart inlinePart = new PreencodedMimeBodyPart(transferEncoding);
try {
inlinePart.setText(contentEnode(data));
inlinePart.setDisposition(Part.INLINE);
inlinePart.setContentID(nameEncode(name));
if(contentType != null){
inlinePart.setHeader("Content-Type", contentType);
}
inlineList.add(inlinePart);
} catch (Exception e) {
logger.warn(e.getMessage(), e);
}
}
protected String nameEncode(String s)throws UnsupportedEncodingException{
return MimeUtility.encodeText(s, encoding, "B");
}
public static String nameEncode(String s, String encoding)throws UnsupportedEncodingException{
return MimeUtility.encodeText(s, encoding, "B");
}
public String encode(){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
encodeToOutputStream(baos);
try {
return baos.toString("iso-8859-1");
} catch (UnsupportedEncodingException e) {
logger.warn(e.getMessage(), e);
}
return null;
}
public void encodeToOutputStream(OutputStream os){
try {
MimeMultipart multipart = new MimeMultipart(subtype);
if((txtContent != null) && (htmlContent != null)){
MimeMultipart contentPart = new MimeMultipart("alternative");
contentPart.addBodyPart(txtContent);
contentPart.addBodyPart(htmlContent);
MimeBodyPart part = new MimeBodyPart();
part.setContent(contentPart);
multipart.addBodyPart(part);
}else if(txtContent != null){
multipart.addBodyPart(txtContent);
}else if(htmlContent != null){
multipart.addBodyPart(htmlContent);
}
for(MimeBodyPart attachment : attachmentList){
multipart.addBodyPart(attachment);
}
for(MimeBodyPart inline : inlineList){
multipart.addBodyPart(inline);
}
MimeMessage message = new MimeMessage(Session.getDefaultInstance(new Properties()));
for(String key : headers.keySet()){
message.setHeader(key, headers.get(key));
}
message.setContent(multipart);
message.writeTo(os);
} catch (Exception e) {
logger.warn(e.getMessage(), e);
}
}
public void encodeToFile(String f){
BufferedOutputStream bos = null;
try {
bos = new BufferedOutputStream(new FileOutputStream(f));
encodeToOutputStream(bos);
} catch (Exception e) {
logger.warn(e.getMessage(), e);
}finally{
if(bos != null){
try {
bos.close();
} catch (IOException e) {
logger.warn(e.getMessage(), e);
}
}
}
}
}
3. 测试
public static void main(String args[])throws Exception{
MimeEncoder encoder = new MimeEncoder("UTF-8");
encoder.setTxtContent("文本内容");
encoder.setHtmlContent("<b>html内容</b><img src='cid:f1'/>");
encoder.addInline("f1", new File("d:/test/内嵌文件.gif"), "image/gif");
encoder.addAttachment(new File("d:/test/附件.txt"), "text/plain");
encoder.encodeToFile("d:/test/mime.eml");
}
执行完测试代码后会生成一个mime.eml文件, 该文件可以使用记事本等文件编辑器打开,也可以使用FoxMail等邮件工具打开。