java 实现邮件发送功能 包含(标题、正文、本地文件、远程文件,多个收件人,多个抄送人等等)

         java 实现邮件发送功能  包含(标题、正文、本地文件、远程文件,多个收件人,多个抄送人等等)

1、pom.xml配置,我这里配置的是1.4.4版本,

*****重点提示,你可以用其他版本的,但假如后续出现文件名过长导致出现 文件名变成.bin,.bat之类的问题,请改回1.4.4版本。

<dependency>
		    <groupId>com.sun.mail</groupId>
		    <artifactId>javax.mail</artifactId>
		    <version>${mail-version}</version>
		</dependency>

 2、控制层

   这里主要是发送远程文件做附件,其他的也可以,加在sendEmail方法里。

/**
	 * 邮件发送,附件是doc/docx/png..等各种文件
	 * @param map
	 * @param request
	 */
	@ResponseBody
	@RequestMapping("/sendMail")
	public R sendtestmail(@RequestBody HashMap<String, Object> map, HttpServletRequest request) {
		String subject="智能文书";
		String content="您好:<br>&emsp;&emsp;您有一份智能文书,请查收!";
		String toAddress = map.get("toAddress")==null?null:map.get("toAddress").toString();
		// 附件处理
		String remoteFile =  map.get("remoteFile") == null ? null : map.get("remoteFile").toString();
        List<String> remoteFileList = new ArrayList<>();
		if (StringUtil.isNotEmpty(remoteFile))
        {
            remoteFileList = Arrays.asList(remoteFile.split(","));
        }
		try {
			SendMailUtil.sendEmail(subject,content,null,remoteFileList,toAddress,null);
		} catch (Exception e) {
            logger.error(e);
            return R.error(ResponseCode.SENDEMAIL_ERROR);
		}
		return R.ok();
	}

 3、邮件发送工具类

package com.yz.robot.utils;

import com.sun.mail.util.MailSSLSocketFactory;
import com.yz.robot.utils.vcode.MyAuthenticator;
import org.springframework.util.CollectionUtils;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.activation.URLDataSource;
import javax.mail.*;
import javax.mail.internet.*;
import java.net.URL;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Properties;

public class SendMailUtil {
	
	/**
	 * 发送邮件
	 * @param subject 主题
	 * @param content 正文内容
	 * @param file 附件 本地文件list
	 * @param remoteFile 附件 远程文件list
	 * @param toAddress 收件人 多个时参数形式:"[email protected],[email protected],[email protected]"
	 * @param ccAddress 抄送人 多个时参数形式:"[email protected],[email protected],[email protected]"
	 * @throws Exception
	 */
	public static void sendEmail(String subject, String content, List<String> file, List<String> remoteFile, String toAddress, String ccAddress) throws Exception {

		//1、发送方的邮件地址和密码
		ConfigRead conf = ConfigRead.getInstance();
		String emailaddress = conf.getConfigItem("emailaddress");
		String emailpassword = conf.getConfigItem("emailpassword");

		// 2、获取相关配置,创建session
		Properties properties = getProperties();
		Session session = Session.getDefaultInstance(properties, new MyAuthenticator(emailaddress, emailpassword));
		// 开启Session的debug模式,这样就可以查看到程序发送Email的运行状态,后续可关闭
		session.setDebug(true);

		// 3. 创建邮件对象message,设置标题、日期、发件人等等
		MimeMessage message = new MimeMessage(session);
		message.setSubject(subject);
		message.setSentDate(new Date());
		message.setFrom(new InternetAddress(emailaddress));
		message.setContent(getMultipart(content,file,remoteFile));

		// 4、收件人、抄送人
		if (StringUtil.isNotEmpty(toAddress))
		{
			message.setRecipients(Message.RecipientType.TO, new InternetAddress().parse(toAddress));
		}
		if (StringUtil.isNotEmpty(ccAddress))
		{
			message.setRecipients(Message.RecipientType.CC, new InternetAddress().parse(ccAddress));
		}

		// 4、发送
		Transport.send(message, message.getAllRecipients());
	}

	/**
	 * 获取properties
	 * @return
	 * @throws Exception
	 */
	public static Properties getProperties() throws Exception{
		//1. 用于存放 SMTP 服务器地址等参数
		Properties properties = new Properties();
		// 主机地址
		properties.setProperty("mail.smtp.host", "smtp.exmail.qq.com");
		//properties.setProperty("mail.smtp.host", conf.getConfigItem("mail.smtp.host"));
		// 邮件协议
		properties.setProperty("mail.transport.protocol", "smtp");
		// 认证
		properties.setProperty("mail.smtp.auth", "true");
		// 端口
		properties.setProperty("mail.smtp.port", "465");

		MailSSLSocketFactory sf = new MailSSLSocketFactory();
		sf.setTrustAllHosts(true);
		properties.put("mail.smtp.ssl.enable", "true");
		properties.put("mail.smtp.ssl.socketFactory", sf);

		return properties;
	}

	/**
	 * 获取Multipart对象,包含正文内容、附件
	 * @return
	 */
	private static Multipart getMultipart(String content, List<String> file, List<String> remoteFile) throws Exception {
		Multipart multipart = new MimeMultipart();
		// 1、向multipart中添加正文
		BodyPart contentBodyPart = new MimeBodyPart();
		contentBodyPart.setContent(content, "text/html;charset=UTF-8");
		multipart.addBodyPart(contentBodyPart);
		// 2、向multipart中添加附件
		if (!CollectionUtils.isEmpty(file))
		{
			for (String url : file) {
				multipart.addBodyPart(getBodyPart(url,FileUtil.getNameByUrl(url),1));
			}
		}
		// 3、向multipart中添加远程附件
		if (!CollectionUtils.isEmpty(remoteFile))
		{
			for (String url : remoteFile){
				multipart.addBodyPart(getBodyPart(FileUtil.encodeURI(url),FileUtil.getNameByUrl(url),2));
			}
		}
		return multipart;
	}

	/**
	 * 获取 bodyPart
	 * @param path 文件路径
	 * @param fileName 文件名称
	 * @param pathType 1、本地文件;2、远程文件
	 * @return
	 */
	public static BodyPart getBodyPart(String path,String fileName,int pathType) throws Exception{
		BodyPart bodyPart = new MimeBodyPart();
		// 根据附件路径获取文件,
		DataHandler dh = null;
		if (pathType == 1){
			dh = new DataHandler(new FileDataSource(path));
		}else if (pathType == 2){
			dh = new DataHandler(new URLDataSource(new URL(path)));
		}
		bodyPart.setDataHandler(dh);
		//MimeUtility.encodeWord可以避免文件名乱码
		System.out.println(MimeUtility.encodeWord(fileName));
		bodyPart.setFileName(MimeUtility.encodeWord(fileName,"gb2312",null));
		//bodyPart.setFileName(MimeUtility.encodeWord(fileName)); 
		return bodyPart;
	}
}

 4、以上就是邮件发送全部代码了,有以下几个注意的地方

  a.远程文件在生成dh之前 (dh = new DataHandler(new URLDataSource(new URL(path)))) ,需要对url进行编码,不能包含中文,例如:

编码前:http://www.baidu.com/api/resource/robot/word/2/婚前协议.doc 

编码后:http://v.shiduai.com/api/resource/robot/word/2/%E5%A9%9A%E5%89%8D%E5%8D%8F%E8%AE%AE.doc

 这里付上方法:你们有好的方法可以用自己的,目的达到就可以了

package com.yz.robot.utils;

import org.springframework.web.multipart.MultipartFile;

import java.net.URLEncoder;

/**
 * @Description: 文件相关工具类
 * @Auther: wuyp
 * @Date: 2018/5/22 10:04
 */
public class FileUtil {
    

    /**
     * 对文件fileUrl进行编码 类似于浏览器的encodeURI编码
     * 例子:编码前:http://www.baidu.com/api/resource/robot/word/2/婚前协议.doc
     *      编码后:http://www.baidu.com/api/resource/robot/word/2/%E5%A9%9A%E5%89%8D%E5%8D%8F%E8%AE%AE.doc
     * @param url
     * @return
     */
    public static String encodeURI(String url) throws Exception
    {
        String encode = URLEncoder.encode(url, "UTF-8");

        return encode.replace("%3A",":").replace("%2F","/");
    }

    /**
     * 根据fileUrl获取 带后缀的文件名称
     *
     * @param url
     * @return
     */
    public static String getNameByUrl(String url)
    {
        if (StringUtil.isEmpty(url))
        {
            return null;
        }
        return url.substring(url.lastIndexOf("/")+1);
    }
}

 b.就是设置文件名的时候要避免乱码,

bodyPart.setFileName(MimeUtility.encodeText(fileName)); 

这个倒是可以处理乱码问题,但是偶尔会出现文件名变成了tcmime.1829.2125.50468.bin等,此时附件下载下来另存为doc也是没问题的,这种处理本地测试完全没问题,但是linux不行,而且不是绝对不行,是偶尔出现。同样是docx文件,一个出现这样,一个文件名正常,目前不知道啥原因,有哪位大佬知道告诉我。。。

(已经知道是文件名过长问题,把文件名改为一个字,立马正常,解决这个问题方法是改为1.4.4版本)

下面这个是解决办法,设置成gb2312后,一切问题都没有了。

bodyPart.setFileName(MimeUtility.encodeWord(fileName,"gb2312",null));
  

---------------------------------------------------------------结束---------------------------------------------------------------------

猜你喜欢

转载自blog.csdn.net/w20228396/article/details/81870675