在Web应用中增加邮件发送功能

本文介绍了如何在Web应用中实现邮件发送,包括后台原理和界面设计,以及在Tomcat中配置JavaMail_JNDI资源时可能遇到的类加载问题。重点讨论了避免类冲突的方法,如将mail.jar放入Tomcat的lib目录,以及在context.xml中配置JNDI资源。同时提醒开发者注意不同环境下的类加载差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、Web应用发送邮件原理和界面

1.1、Web应用发送邮件后台原理



上图中,蓝色圆代表一个后台线程或者是单独的邮件发送模块。启动单独的一个邮件发送模块或者创建一个后台线程负责发送邮件,Servlet只是负责将邮件发送任务扔到队列中,让邮件模块或者线程慢慢发送,以便Servlet能够及时返回。

1.2、Web发送邮件页面示意图



还不如直接用outlook撰写好一封邮件后,将此邮件上传到服务器,然后用new MimeMessage(session,fis)的方式创建出Message对象。

二、Tomcat的JavaMail_JNDI资源与类加载问题

2.1 Tomcat中JavaMail支持与冲突

1、用普通方式在web应用程序中增加邮件发送功能
      先演示在eclipse没有导入mail.jar可以编译,但部署运行有问题的原因
2、用Tomcat支持的JNDI资源方式,步骤:
      配置JNDI资源。
      将mail.jar拷贝到<tomcat_home>/lib目录下。
      在Java程序中使用JNDI API获得mail的session对象。
3、分析类加载的冲突问题


使用JNDI的方式配置javamail,如果tomcat的lib目录和web-inf/lib目录中都放置了mail.jar包,java虚拟机中将有两份类字节码,这两份类字节码相当于两个不同的类。在eclipse中开发这个项目时,要注意开发时环境与运行时环境,对于mail.jar包中,包含在j2ee库中了,必须手工部署到tomcat的lib目录中。
在上次录视频讲类加载时,一个技巧问题没有向大家展现,非常遗憾。如果使用如下两条语句打印出类加载器的名称,让大家看到实实在在的结果,就好多了:
System.out.println(initCtx.lookup("java:comp/env/mail/Session").getClass().getClassLoader().getClass().getName());
System.out.println(Session.class.getClassLoader().getClass().getName());


注意点:
①在WebRoot/META-INF目录下创建context.xml文件,并进行如下配置;


在context.xml中进行如下配置:



②将mail.jar拷贝到tomcat8.5.9\lib目录下:



③解决javax.mail.Session cannot be cast to javax.mail.Session错误
移除WEB-INF/lib下面的mail.jar这个包和引用的外部的mail.jar包,使用上面tomcat配置的mail.jar这个jar包。

具体代码如下:

package javamail3;

import java.io.IOException;

import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class SendMailServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, 
			HttpServletResponse response)
			throws ServletException, IOException {

		doPost(request, response);
	}


	public void doPost(HttpServletRequest request, 
			HttpServletResponse response)
			throws ServletException, IOException {

		try {
			//Demo2.main(new String[]{});
			//初始化容器
			Context initCtx = new InitialContext();
			//查找子容器
			Context envCtx = (Context) initCtx.lookup("java:comp/env");
			//在容器中查找Session,根据context.xml中的配置获取Session
			Session session = (Session) envCtx.lookup("mail/Dog");
			/*System.out.println(envCtx.lookup("mail/Dog")
					.getClass()
					.getClassLoader().getClass().getName());
			System.out.println(Session.class.getClassLoader()
					.getClass().getName());*/
			
			Message message = new MimeMessage(session);
			message.setFrom(new InternetAddress("************@163.com"));
			InternetAddress[] to = new InternetAddress[1];
			to[0] = new InternetAddress("************@qq.com");
			message.setRecipients(Message.RecipientType.TO, to);
			message.setSubject("ha");//设置邮件主题
			message.setText("你给我的爱还在不在?");//设置邮件主题
			Transport transport = session.getTransport();
			//连接163的服务器
			transport
			.connect("smtp.163.com", "************@163.com", "abc123");
			transport.sendMessage(message, to);
			transport.close();//关闭连接
			response.getWriter().print("OK!");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}
上述代码经过自己测试成功!


参考书籍:《Java邮件开发详解》

参考视频:《传智播客_张孝祥_Java邮件开发教程》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值