javaMail API
javaMail是SUN公司提供的针对邮件的API 。 两个jar包 mail.jar 和 activation.jar
java mail中主要类:javax.mail.Session、javax.mail.internet.MimeMessage、javax.mail.Transport。
Session | 表示会话,即客户端与邮件服务器之间的会话!想获得会话需要给出账户和密码,当然还要给出服务器名称。在邮件服务中的Session对象,就相当于连接数据库时的Connection对象。 |
MimeMessage | 表示邮件类,它是Message的子类。它包含邮件的主题(标题)、内容,收件人地址、发件人地址,还可以设置抄送和暗送,甚至还可以设置附件。 |
Transport | 用来发送邮件。它是发送器! |
第一步:获得Session
第二步:创建MimeMessage对象
第三步:发送邮件
javaMail 代码分析
代码在web项目中没有任何问题,但是在java中用@Test做测试时会报错,
到下面路径中找到javaee.jar文件,把javax.mail删除!!!
D:Program FilesMyEclipseCommonpluginscom.genuitec.eclipse.j2eedt.core_10.0.0.me201110301321datalibrarysetEE_5
需要注意: 如果出现如下报错信息:
javax.mail.AuthenticationFailedException: failed to connect
基本上密码有问题,这个密码并不是邮箱帐号的私人密码,而是授权密码。 关于邮箱授权密码请自行百度。
/** * 文本邮件 * @throws MessagingException * @throws javax.mail.MessagingException */ @Test public void fun() throws MessagingException, javax.mail.MessagingException{ /* * 1. 得到Session * 导包: java.util.properties;import javax.mail.Authenticator;import javax.mail.Session; */ Properties props = new Properties(); props.setProperty("mail.host", "smtp.163.com");//设置服务器主机名 props.setProperty("mail.smtp.auth", "true"); //设置需要认证 //Authenticator是一个接口表示认证器,即校验客户端的身份。我们需要自己来实现这个接口,实现这个接口需要使用账户和密码。 Authenticator auth = new Authenticator(){ protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication("zhaoyuqiang2017","z123456"); //用户名和密码 } }; Session session = Session.getInstance(props,auth); /* * 2. 创建MimeMessage * import javax.mail.internet.MimeMessage; * RecipientType.TO正常 * RecipientType.CC抄送 * RecipientType.BCC暗送 */ MimeMessage msg = new MimeMessage(session); msg.setFrom(new InternetAddress("zhaoyuqiang2017@163.com"));//设置发件人 msg.setRecipients(RecipientType.TO, "425680992@qq.com");//设置收件人 msg.setSubject("这是标题");//邮件标题 msg.setContent("我爱你!","text/html;charset=utf-8");//设置邮件内容 /* * 3.发邮件 */ Transport.send(msg); }
/** * 附件邮件 * @throws AddressException * @throws MessagingException * @throws IOException */ @Test public void fun1() throws AddressException, MessagingException, IOException{ Properties props = new Properties(); props.setProperty("mail.host", "smtp.163.com"); props.setProperty("mail.smtp.auth", "true"); Authenticator auth = new Authenticator(){ @Override protected PasswordAuthentication getPasswordAuthentication() { // TODO Auto-generated method stub return new PasswordAuthentication("zhaoyuqiang2017","z123456"); } }; Session session = Session.getInstance(props,auth); MimeMessage msg = new MimeMessage(session); msg.setFrom(new InternetAddress("zhaoyuqiang2017@163.com"));//设置发件人 msg.setRecipients(RecipientType.TO, "425680992@qq.com");//设置收件人 msg.setSubject("这是标题-有附件");//邮件标题 /** * 有附件的内容 * 邮件体为多部件形式 * */ /* * 1. 创建一个多部件的部件 MimeMultipart * MimeMultipart就是一个集合,装载多个主体部件 * 2. 创建两个主体部件MimeBodyPart,一个是文本part1 * 3. 设置主体部件的内容 * 4. 把主体部件加到list集合中 * 5. 创建两个主体部件MimeBodyPart,一个是附件part2 * 6. 设置附件的内容 * 7. 设置显示的文件名称 * 8. 把主体部件加到list集合中 * 3. 把MimeMultipart设置给MimeMessage的内容 */ MimeMultipart list = new MimeMultipart(); MimeBodyPart part1 = new MimeBodyPart(); part1.setContent("我爱你,","text/html;charset=utf-8"); list.addBodyPart(part1); MimeBodyPart part2 = new MimeBodyPart(); part2.attachFile(new File("D:/吉泽明步.jpg")); part2.setFileName(MimeUtility.encodeText("大美女.jpg"));//encodeText解决乱码 list.addBodyPart(part2); msg.setContent(list); Transport.send(msg); }
为了简化代码,在实际操作中往往需要把重复代码进行封装,需要导入itcast-tools.jar(下载:https://files.cnblogs.com/files/zyuqiang/itcast-tool.rar ) ,在本文附加的项目中,会把邮件相关的参数信息都放在配置文件中。
/** * 文本邮件 * 用小工具来简化邮件 * @throws MessagingException * @throws IOException */ @Test public void fun() throws MessagingException, IOException{ /* * 1. 得到Session */ Session session = MailUtils.createSession("smtp.163.com", "zhaoyuqiang2017","z123456"); /* * 2. 创建邮件对象 */ Mail mail = new Mail("zhaoyuqiang2017@163.com", "425680992@qq.com","这个是标题-工具", "用工具爱你"); /** * 添加附件 * 2个附件 */ AttachBean ab1 = new AttachBean(new File("D:/吉泽明步.jpg"), "美女.jpg"); AttachBean ab2 = new AttachBean(new File("D:/吉泽明步.jpg"), "小美女.jpg"); mail.addAttach(ab1); mail.addAttach(ab2); /* * 3. 发送 */ MailUtils.send(session, mail); }
项目案例_用户注册时发送邮件到指定邮箱,并且激活。
说明: 用户注册,填入指定邮箱,系统会自动发送到指定邮箱一个超链接,让用户去指定邮箱点击一个超链接激活,激活后才可以正常登陆。
本项目把邮件相关的参数信息都放在配置文件中。
1 CREATE TABLE tb_user( 2 uid CHAR(32) PRIMARY KEY,/*主键*/ 3 email VARCHAR(50) NOT NULL,/*邮箱*/ 4 `code` CHAR(64) NOT NULL,/*激活码*/ 5 state BOOLEAN/*用户状态,有两种是否激活*/ 6 );
只给出核心源码,全部项目(包括c3p0文件、邮件文件等)请下载该项目查看, 项目的运行,注意需要修改c3p0配置文件中数据库名称
1 package cn.kmust.mail.web.servlet; 2 3 4 import java.io.IOException; 5 import java.text.MessageFormat; 6 import java.util.Properties; 7 8 9 import javax.mail.MessagingException; 10 import javax.mail.Session; 11 import javax.servlet.ServletException; 12 import javax.servlet.http.HttpServletRequest; 13 import javax.servlet.http.HttpServletResponse; 14 15 import cn.itcast.commons.CommonUtils; 16 import cn.itcast.mail.Mail; 17 import cn.itcast.mail.MailUtils; 18 import cn.itcast.servlet.BaseServlet; 19 import cn.kmust.mail.domin.User; 20 import cn.kmust.mail.exception.UserException; 21 import cn.kmust.mail.service.UserService; 22 23 public class UserServlet extends BaseServlet { 24 private UserService userService = new UserService(); 25 /** 26 * 注册 27 * 邮件发送到指定邮箱 28 * @param request 29 * @param response 30 * @return 31 * @throws ServletException 32 * @throws IOException 33 */ 34 public String regist(HttpServletRequest request, HttpServletResponse response) 35 throws ServletException, IOException { 36 37 User form = CommonUtils.toBean(request.getParameterMap(), User.class); 38 /* 39 * 补齐code 40 */ 41 form.setCode(CommonUtils.uuid()+CommonUtils.uuid()); 42 /* 43 * 调用service的注册功能 44 */ 45 userService.regist(form); 46 /* 47 * 发送邮件,(包含"缺少收不到重发"功能) 48 * 准备配置文件email_template.properties 49 * 发送的邮件方信息放在配置文件中 50 * 发送内容为一个超链接,超链接到该类的active方法 51 * <a href ="http://localhost:8080/项目名字/UserServlet?method=active&code={0}">点击这里完成激活 </a> 52 * 获取配置文件的内容 53 * 加载配置文件到props中 54 * 获取主机、发送用户、授权密码、发送邮件、发件人、发件主题、发送内容 55 * 得到Session 56 * 创建邮件对象 57 * 发邮件 58 */ 59 Properties props = new Properties(); 60 props.load(this.getClass().getClassLoader(). 61 getResourceAsStream("email_template.properties")); 62 String host = props.getProperty("host"); 63 String uname = props.getProperty("uname"); 64 String pwd = props.getProperty("pwd"); 65 String from = props.getProperty("from"); 66 String to = form.getEmail(); 67 String subject = props.getProperty("subject"); 68 String content = props.getProperty("content"); 69 content = MessageFormat.format(content, form.getCode());//替换{0}占位符 70 71 Session session = MailUtils.createSession(host, uname, pwd); 72 Mail mail = new Mail(from,to,subject,content); 73 try { 74 MailUtils.send(session, mail); 75 } catch (MessagingException e) { 76 } 77 /* 78 * 保存成功信息到msg.jsp 79 */ 80 request.setAttribute("msg", "恭喜您,注册成功!请马上到邮箱激活!"); 81 return "f:/msg.jsp"; 82 } 83 /** 84 * 激活功能 85 * @功能 当用户点击邮件中的完成激活连接时,访问这个方法 86 * 调用service的激活方法修改用户状态 87 * @param request 88 * @param response 89 * @return 90 * @throws ServletException 91 * @throws IOException 92 * @throws 93 */ 94 public String active(HttpServletRequest request, HttpServletResponse response) 95 throws ServletException, IOException { 96 /* 97 * 1. 获取参数激活码 98 * 2. 调用service方法完成激活 99 * 如果出现异常,保存异常信息到request域中,转发到msg.jsp 100 * 3. 成功,保存成功信息到request域,转发msg.jsp 101 */ 102 String code = request.getParameter("code"); 103 try { 104 userService.active(code); 105 request.setAttribute("msg", "恭喜,您激活成功!请登陆"); 106 } catch (UserException e) { 107 request.setAttribute("msg", e.getMessage()); 108 } 109 return "f:/msg.jsp" ; 110 } 111 112 }
1 package cn.kmust.mail.service; 2 3 import cn.kmust.mail.dao.UserDao; 4 import cn.kmust.mail.domin.User; 5 import cn.kmust.mail.exception.UserException; 6 7 public class UserService { 8 private UserDao userDao = new UserDao(); 9 /** 10 * 激活功能 11 * @param code 12 * @throws UserException 13 */ 14 public void active(String code) throws UserException { 15 /* 16 * 1. 按激活码查询用户 17 * 2. user不存在,激活码错误 18 * 3. 校验用户状态,如果已激活,说明二次激活,抛出异常 19 * 4. 第一次激活,则修改用户状态为true,表明已经激活 20 */ 21 User user = userDao.findByCode(code); 22 System.out.println("激活状态测试:"+user.isState()); 23 if(user == null ) 24 throw new UserException("激活码无效!"); 25 if(user.isState()) 26 throw new UserException("您已经激活过了!"); 27 userDao.updataState(user.getUid(),true); 28 29 } 30 /** 31 * 注册功能 32 * @param form 33 */ 34 public void regist(User form) { 35 userDao.add(form); 36 } 37 }
1 package cn.kmust.mail.dao; 2 3 import java.sql.SQLException; 4 import org.apache.commons.dbutils.QueryRunner; 5 import org.apache.commons.dbutils.handlers.BeanHandler; 6 7 import cn.itcast.jdbc.TxQueryRunner; 8 import cn.kmust.mail.domin.User; 9 10 public class UserDao { 11 private QueryRunner qr = new TxQueryRunner(); 12 /** 13 * 通过激活码查询用户 14 * @param code 15 * @return 16 */ 17 public User findByCode(String code) { 18 try{ 19 String sql = "select * from tb_user where code=?" ; 20 return qr.query(sql, new BeanHandler<User>(User.class),code); 21 }catch(SQLException e){ 22 throw new RuntimeException(e); 23 } 24 } 25 /** 26 * 添加用户 27 * @param form 28 */ 29 public void add(User user) { 30 try{ 31 String sql = "insert into tb_user value(?,?,?,?)"; 32 Object[] params ={user.getUid(),user.getEmail(),user.getCode(),user.isState()}; 33 qr.update(sql,params); 34 }catch(SQLException e){ 35 throw new RuntimeException(e); 36 } 37 38 } 39 /** 40 * 成功激活后修改状态为已激活 41 * @param uid 42 * @param b 43 */ 44 public void updataState(String uid, boolean state) { 45 try{ 46 String sql = "update tb_user set state=? where uid=?"; 47 qr.update(sql,state,uid); 48 }catch(SQLException e){ 49 throw new RuntimeException(e); 50 } 51 52 } 53 54 }