先写一个邮件工具类吧
来源:互联网 发布:windows软件包2016 编辑:程序博客网 时间:2024/05/16 05:22
写一个邮件发送大概有多麻烦
首先是初始化邮件工具类,初始化主要是创建一个邮件的会话,并获取该会话的mimeMessage对象。除此之外就是设置一些参数包括发件服务器,发件人账号密码等。
设置发件人信息,设置发件人通过mimeMessage对象的setFrom设置,它接收一个InternetAddress对象。如:”InternetAddress from = new InternetAddress(sender_username)
”
设置收件人信息,设置收件人通过mimeMessage对象的setRecipient方法,它可以接受两个参数,一个指定收件类型,一个指定收件人信息,该信息也必须是InternetAddress对象。
设置邮件主题,通过setSubject指定。
添加正文和附件,通过new mimeMultipart()
来实例化一个Multipart对象,邮件的所有实体都被添加至该对象。
添加正文,先实例化一个BodyPart对象,通过new MimeBodyPart()生成,调用bodyPart的setContent来设置正文,需要强调的是"text/html;charset=UTF-8"
这个不能少,指明发过去的邮件类型和编码格式。设置完毕后添加到Multipart对象中。
添加附件,大概最复杂的部分就是添加附件了。
首先是获取附件的File对象,通过File对象生成DataSource对象,通过DataSource对象生成DataHandler对象,调用BodyPart对象的setDataHandler方法将DataHandler对象传递进去,最后还要把BodyPart对象放进Multipart对象中。
把设置好的Multipart对象放进message对象中,通过setContent方法,最后一定一定千万要记得saveChanges。
最后的最后,创建一个实例,它相当于一个邮箱,如:transport = session.getTransport("smtp")
这里指定邮箱服务器为SMTP,然后验证它是否可用,通过connect方法验证。
最后的最后的最后就是发送邮件了,transport.sendMessage(message, message.getAllRecipients())
。
高端名词的低端解释
什么是mimeMessage?
在知道这个之前,我们需要先知道什么是MIME。MIME在中国被叫做多用途互联网邮件拓展,为什么会有MIME呢?这是因为旧邮件标准是不允许传输7位ASSIC码以外的邮件,因此创造了MIME的生存空间。而mimeMessage表示MIME样式的电子邮件,想要创建新的MIME样式消息的客户端将实例化一个空的MimeMessage对象,然后用适当的属性和内容填充它。在创建空的MEMI消息时必须在Property中添加如下参数:
properties.put("mail.smtp.auth", "true")
,据说只有指定mail.smtp.auth字段为TRUE才能通过验证。
什么是InternetAddress?
此类表示使用RFC822语法的Internet电子邮件地址。说白了就是专门用来表示电子邮件地址的。至于为什么这样表示,涉及到比较复杂的加密算法,大概是为了安全,大概是为了其他的什么,只是为了发一封邮件的我这里不追究。
什么是Multipart对象?
这个具体要看回MIME的概述了。之前说过MIME存在的意义是扩展旧邮件标准的不足,就是不能发送ASSIC以外的讯息。而在MIME支持的类型里面就有一种称为Multipart,它的用途是用于连接消息体的多个部分构成一个消息,这些部分可以是不同类型的数据。说白了就类似我们的Map一样的东西。
下面是MIME支持的类型和子类型(来自维基)
type有下面的形式。
- Text:用于标准化地表示的文本信息,文本消息可以是多种字符集和或者多种格式的;
- Multipart:用于连接消息体的多个部分构成一个消息,这些部分可以是不同类型的数据;
- Application:用于传输应用程序数据或者二进制数据;
- Message:用于包装一个E-mail消息;
- Image:用于传输静态图片数据;
- Audio:用于传输音频或者音声数据;
- Video:用于传输动态影像数据,可以是与音频编辑在一起的视频数据格式。
subtype用于指定type的详细形式。content-type/subtype配对的集合和与此相关的参数,将随着时间而增长。为了确保这些值在一个有序而且公开的状态下开发,MIME使用Internet Assigned Numbers –
- Authority (IANA)作为中心的注册机制来管理这些值。常用的subtype值如下所示:
- text/plain(纯文本)
- text/html(HTML文档)
- application/xhtml+xml(XHTML文档)
- image/gif(GIF图像)
- image/jpeg(JPEG图像)【PHP中为:image/pjpeg】
- image/png(PNG图像)【PHP中为:image/x-png】
- video/mpeg(MPEG动画)
- application/octet-stream(任意的二进制数据)
- application/pdf(PDF文档)
- application/msword(Microsoft Word文件)
- application/vnd.wap.xhtml+xml (wap1.0+)
- application/xhtml+xml (wap2.0+)
- message/rfc822(RFC 822形式)
- multipart/alternative(HTML邮件的HTML形式和纯文本形式,相同内容使用不同形式表示
- application/x-www-form-urlencoded(使用HTTP的POST方法提交的表单)
- multipart/form-data(同上,但主要用于表单提交时伴随文件上传的场合)
在应用场景,邮件是怎么传递附件的呢?这一点我做过很多尝试,qq上的附件肯定不是直接从本地获取附件,它至少是缓存了附件或是将附件上传到服务器上。对于客户端缓存附件这个我不是很了解,于是这里我们假设场景为发送附件时,将附件上传至服务器,之后从服务器中获取附件添加至邮件的Multipart中。那么在发送邮件之前我们要实现上传的工具类。上传比较简单,核心语句就是transferTo(转存),将获取到的MultipartFile对象转存到另一实际存在的路径/文件名(一般是加密后的文件名)中。这里不赘述。
public static String upload(MultipartFile file, String path){ String filename = file.getOriginalName(); UUID uuid = UUID.randomUUID(); String temp = filename.substring(0, filename.lastIndexOf(".")); String retFilename = "" + filename.replace(temp, uuid.toString());//uuid代替文件名 File target = new File(path, retFilename);//构造目标文件 if(!File.exist(target)){ File.mkdir() } file.transferTo(target);//转存数据到目标文件 return retFilename;//返回加密后的文件名}
上面是上传的一个示例,记住!这些代码是在Spring框架下执行的,MultipartFile是Spring框架下一个临时存储文件的接口。所以在编写代码的时候先搭个Spring框架吧。不过这不是我关心的内容,既然上传完成了,那么继续编写邮件类吧。
编写邮件类的我们有时候会通过xml配置来配置发件人发件服务器等信息,这里我们只通过Java进行配置,而不经过xml。
首先思考我们大概需要些什么信息,然后把一些必要的东西封装进对象,这样会让我们的发邮件的方法签名更加简洁好看。
然后看代码吧。。。不知道怎么编了。。。
public class MailUtils { private MimeMessage message; private Session session; private Properties properties = new Properties(); private Transport transport; private String mailhost; private String senderAccount; private String senderPassword; public void init(TEmailSetting email, boolean debug){ this.mailhost = email.getSendServer(); this.senderAccount = email.getAccount(); this.senderPassword = email.getPassword(); properties.put("mail.smtp.auth", "true"); session = Session.getInstance(properties); session.setDebug(debug); message = new MimeMessage(session); } public String sendMail(String subject, String htmlContent, String[] receives, List<TAnnex> annexs, TEmailSetting email) throws MessagingException, UnsupportedEncodingException{ this.init(email, true); //设置发件人 InternetAddress from = new InternetAddress(senderAccount); message.setFrom(from); //设置收件人 for(String receive : receives){ InternetAddress to = new InternetAddress(receive); message.addRecipient(RecipientType.TO, to); } //设置邮件主题 message.setSubject(subject); //设置正文附件混合的对象 Multipart multipart = new MimeMultipart(); //设置邮件正文 BodyPart contentPart = new MimeBodyPart(); contentPart.setContent(htmlContent, "text/html;charset=UTF-8"); multipart.addBodyPart(contentPart); //设置附件 for(TAnnex annex : annexs){ File file = new File(annex.getAnnexUrl(), annex.getEncryptName()); if(file.exists()){ BodyPart annexPart = new MimeBodyPart(); DataSource source = new FileDataSource(file); DataHandler dh = new DataHandler(source); annexPart.setDataHandler(dh); annexPart.setFileName(MimeUtility.encodeWord(annex.getOriginalName())); multipart.addBodyPart(annexPart); } } message.setContent(multipart); //保存邮件 message.saveChanges(); //实例化发送实体 transport = session.getTransport("smtp"); //创建和邮件服务器的连接 transport.connect(mailhost, senderAccount, senderPassword); //发邮件 transport.sendMessage(message, message.getAllRecipients()); //关闭连接,这里我不知道不关闭会怎样,但是我看到这种都是习惯性的关闭的 transport.close(); return "success"; }}
这里引用一下某大神对发邮件的过程的解释。发邮件的具体过程如下:
所以大概就是这样,那个邮件类是根据我需求写的,因为公司的邮件工具不符合场景,所以自己写了一个。所以有看不懂的地方就算了吧。虽然说得真的有人看一样。。。
看着大神图片然后看代码其实异常简单,我们不过是创造了三个对象session对象,message对象,transport对象,然后连接transport和SMTP服务器,然后发送message到SMTP服务器,而怎么构造一个message对象呢?这其实就是模拟了我们写邮件的过程,最后发送!结束!
- 先写一个邮件工具类吧
- python写的一个邮件收发工具
- 先写一个
- 自己写的一个发送邮件类
- 一个发送邮件的工具类
- 先写一篇吧。
- 写C,先安装好工具
- 先写一个简单的例子
- C# 写的一个发送邮件的类
- android写一个sharepreference工具类
- 自己写一个数据库连接工具类
- 自己写的一个SP工具类
- 先定一个小目标,比如写一个直播类APP出来
- 写一个数据库工具
- 想写一个发送邮件的程序,
- python写的一个邮件发生器
- 用Python写一个发邮件模块
- java邮件工具类
- 什么样的代码才算得上是好代码
- L1-003. 个位数统计
- CommonJS规范
- How tomcat works——15 Digester
- 可变个数形参方法
- 先写一个邮件工具类吧
- 时间序列分析
- android.os.SystemProperties和android.os.Environment
- 程序员薪水差距在哪里?
- bzero()与 memset()等的区别
- javascript dom-文档结构和遍历
- 函数响应式编程(FRP)思想
- 双边滤波算法数学模型分析
- 小雷的冰茶几——并查集