先写一个邮件工具类吧

来源:互联网 发布: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对象呢?这其实就是模拟了我们写邮件的过程,最后发送!结束!

0 0
原创粉丝点击