Java Web基础入门第九十九讲 JavaMail开发——在WEB应用中集成邮件发送程序
发布日期:2021-06-30 18:04:30 浏览次数:3 分类:技术文章

本文共 7562 字,大约阅读时间需要 25 分钟。

前言:现在很多的网站都提供有用户注册功能,通常我们注册成功之后就会收到一封来自注册网站的邮件。邮件里面的内容可能包含了我们注册的用户名和密码以及一个激活账户的超链接等信息。今天我们也来实现一个这样的功能,用户注册成功之后,就将用户的注册信息以Email的形式发送到用户的注册邮箱当中,实现发送邮件功能就得借助于JavaMail API了。

搭建开发环境

创建Web项目

在这里插入图片描述

创建用户注册页面

在WebRoot根目录下创建一个用户注册页面,即register.jsp。

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%>
用户注册页面
用户名:
密码:
电子邮箱:

创建全局消息显示页面

同样,在WebRoot根目录下创建一个全局消息显示页面,即message.jsp。

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%>
全局消息显示页面${
message }

编写处理用户注册程序

开发环境搭建好了之后,接下来我们就要编写处理用户注册的程序了。

开发封装用户注册信息的JavaBean

在cn.liayun.domain包中新建一个封装用户注册信息的JavaBean,即User.java。

package cn.liayun.domain;public class User {
private String username; private String password; private String email; public String getUsername() {
return username; } public void setUsername(String username) {
this.username = username; } public String getPassword() {
return password; } public void setPassword(String password) {
this.password = password; } public String getEmail() {
return email; } public void setEmail(String email) {
this.email = email; } }

编写处理用户注册的Servlet

某人登录网站之后,他会进入到用户注册页面,为自己注册该网站的一个用户。这个时候,服务器端的一个RegisterServlet来处理该用户注册请求。首次编写处理用户注册请求的RegisterServlet,其代码可能是这样的:

在这里插入图片描述
当用户注册成功后,就应向用户发送一封邮件。所以,我们还得编写邮件发送功能。于是,在cn.liayun.utils包中新建一个发送邮件的工具类,即SendMail.java。

package cn.liayun.utils;import java.util.Properties;import javax.mail.Message;import javax.mail.MessagingException;import javax.mail.Session;import javax.mail.Transport;import javax.mail.internet.AddressException;import javax.mail.internet.InternetAddress;import javax.mail.internet.MimeMessage;import cn.liayun.domain.User;//将SendMail这个改成一个线程类public class SendMail {
//管理这个网站账户的邮件服务器是哪一台? private static String host = "smtp.163.com"; //网站要给注册的用户发送邮件,应该使用一个账户进行发送(也就是说网站自己要有一个账户) private static String email = "yerenyuan10001@163.com"; private static String username = "yerenyuan10001"; private static String password = "邮箱密码"; private User user;//到底给哪个用户发送邮件 public SendMail(User user) {
super(); this.user = user; } public static void send(User user) throws Exception {
Properties prop = new Properties(); prop.setProperty("mail.host", host); prop.setProperty("mail.transport.protocol", "smtp"); Session session = Session.getInstance(prop); Message message = createMessage(session, user); Transport ts = session.getTransport(); ts.connect(username, password); ts.sendMessage(message, message.getAllRecipients()); ts.close(); } public static Message createMessage(Session session, User user) throws AddressException, MessagingException {
MimeMessage message = new MimeMessage(session); message.setFrom(new InternetAddress(email)); message.setRecipient(Message.RecipientType.TO, new InternetAddress(user.getEmail())); message.setSubject("美美侠计算机系统有限公司"); String content = "恭喜您,注册成功,您注册的用户名:" + user.getUsername() + ",您注册的密码是:" + user.getEmail() + ",请好好保管,忘了找谁!!"; message.setContent(content, "text/html;charset=UTF-8"); message.saveChanges(); return message; } }

似乎大功告成了,但问题没有你想的这么简单。如果RegisterServlet的代码就像上面那样写,那么会有一个很致命的问题。用户填写完其注册信息一点注册按钮,就会找这个RegisterServlet,这个RegisterServlet就向数据库中注册用户。紧接着,就向用户发送一封邮件,然而这个发邮件的过程可能是一个很慢的过程,因为它还需要连接邮件服务器。有时候,网络不好,发邮件这个动作可能要花费10分钟。这个时候,由于现在是一个线程在跑,向用户发送邮件的代码没有执行完,就不会轮到下面这句代码来执行。

在这里插入图片描述
所以,在实际开发里面,程序绝对不能这样写!那么这个程序应该怎么改呢?要多线程,也即是说在往数据库中注册用户的时候,同时应该启动一个单独的线程,给用户发送邮件。故我们要将SendMail这个类改成一个线程类。
在这里插入图片描述
在该案例中,我都会讲解。先讲第一种方式,即SendMail类要继承Thread类,并重写run方法。

package cn.liayun.utils;import java.util.Properties;import javax.mail.Message;import javax.mail.MessagingException;import javax.mail.Session;import javax.mail.Transport;import javax.mail.internet.AddressException;import javax.mail.internet.InternetAddress;import javax.mail.internet.MimeMessage;import cn.liayun.domain.User;//将SendMail这个改成一个线程类public class SendMail extends Thread {
//管理这个网站账户的邮件服务器是哪一台? private String host = "smtp.163.com"; //网站要给注册的用户发送邮件,应该使用一个账户进行发送(也就是说网站自己要有一个账户) private String email = "yerenyuan10001@163.com"; private String username = "yerenyuan10001"; private String password = "邮箱密码"; private User user;//到底给哪个用户发送邮件 public SendMail(User user) {
super(); this.user = user; } @Override public void run() {
try {
Thread.sleep(1000 * 30);//模拟网络延迟,等待30秒 send(user); } catch (Exception e) {
throw new RuntimeException(e); } } public void send(User user) throws Exception {
Properties prop = new Properties(); prop.setProperty("mail.host", host); prop.setProperty("mail.transport.protocol", "smtp"); Session session = Session.getInstance(prop); Message message = createMessage(session, user); Transport ts = session.getTransport(); ts.connect(username, password); ts.sendMessage(message, message.getAllRecipients()); ts.close(); } public Message createMessage(Session session, User user) throws AddressException, MessagingException {
MimeMessage message = new MimeMessage(session); message.setFrom(new InternetAddress(email)); message.setRecipient(Message.RecipientType.TO, new InternetAddress(user.getEmail())); message.setSubject("美美侠计算机系统有限公司"); String content = "恭喜您,注册成功,您注册的用户名:" + user.getUsername() + ",您注册的密码是:" + user.getEmail() + ",请好好保管,忘了找谁!!"; message.setContent(content, "text/html;charset=UTF-8"); message.saveChanges(); return message; } }

此时,RegisterServlet的代码就要修改为:

在这里插入图片描述
然后,再来讲第二种实现多线程的方式,即SendMail类要实现Runnable接口,并覆盖Runnable接口中的run方法。

package cn.liayun.utils;import java.util.Properties;import javax.mail.Message;import javax.mail.MessagingException;import javax.mail.Session;import javax.mail.Transport;import javax.mail.internet.AddressException;import javax.mail.internet.InternetAddress;import javax.mail.internet.MimeMessage;import cn.liayun.domain.User;public class SendMail implements Runnable {
//管理这个网站账户的邮件服务器是哪一台? private String host = "smtp.163.com"; //网站要给这个用户发送邮件,应该使用一个账户进行发送(也就是说网站自己要有一个账户) private String email = "yerenyuan10001@163.com"; private String username = "yerenyuan10001"; private String password = "邮箱密码"; private User user;//到底给哪个用户发送邮件 public SendMail2(User user) {
this.user = user; } @Override public void run() {
try {
Thread.sleep(1000 * 30);//模拟网络延迟,等待30秒 send(user); } catch (Exception e) {
throw new RuntimeException(e); } } public void send(User user) throws Exception {
Properties prop = new Properties(); prop.setProperty("mail.host", host); prop.setProperty("mail.transport.protocol", "smtp"); Session session = Session.getInstance(prop); Message message = createMessage(session, user); Transport ts = session.getTransport(); ts.connect(username, password); ts.sendMessage(message, message.getAllRecipients()); ts.close(); } public Message createMessage(Session session, User user) throws AddressException, MessagingException {
MimeMessage message = new MimeMessage(session); message.setFrom(new InternetAddress(email)); message.setRecipient(Message.RecipientType.TO, new InternetAddress(user.getEmail())); message.setSubject("美美侠计算机系统有限公司"); String content = "恭喜您,注册成功,您注册的用户名:" + user.getUsername() + ",您注册的密码是:" + user.getEmail() + ",请好好保管,忘了找谁!!"; message.setContent(content, "text/html;charset=UTF-8"); message.saveChanges(); return message; }}

此时,RegisterServlet的代码就要修改为:

在这里插入图片描述
最后,用户注册完成之后就能收到一封网站给发过来的邮件。
在这里插入图片描述
现在很多网站都有这样的功能,用户注册完成之后,网站根据我们注册时填写的邮箱给我们一封Email,然后点击Email中的超链接去激活我们的用户,这种功能就是这样实现的。
在总结使用JavaMail发送邮件时发现,将邮件发送到sina或者sohu的邮箱时,不一定能够马上收取得到邮件,总是有延迟,有时甚至会延迟很长的时间,甚至会被当成垃圾邮件来处理掉,或者干脆就拒绝接收,有时候为了看到邮件发送成功的效果,要等半天,实属无奈啊!

转载地址:https://liayun.blog.csdn.net/article/details/92443423 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:入门Struts1第六讲——使用Struts1框架改造在线网上书店
下一篇:Java基础加强第五讲 泛型(下)——泛型类及其应用

发表评论

最新留言

能坚持,总会有不一样的收获!
[***.219.124.196]2024年04月22日 13时44分52秒