目标:实现一个基于Web的可以发送附件的邮件程序。(涉及的知识点:文件上传+邮件发送)
知识点引入:
文件上传:开发的Web应用是基于HTTP协议的,工作在Request/Response模式下。在这种模式下,用户通过浏览器访问Web应用中的内容,都会先通过浏览器给服务器发送一个对资源的请求,服务器接到这个请求后,会把用户所请求的资源返回给浏览器。接下来的一点很少有人会思考到:其实文件上传与浏览器发送请求性质相同,都是向服务器传递信息。一般情况下,浏览器给服务器发送的请求信息都是一些简单的文本信息,而服务器返回给用户的信息是比较复杂的信息,会包括头信息,文本信息,图片文件的内容等。而通过浏览器上传文件给服务器,与正常的访问不同,用户通过浏览器给服务器发送的是比较复杂的信息,而浏览器返回的可能是简单的信息。(这段话没有什么实际的价值,但是本人觉得挺有意思的,可以将文件上传与发送请求联系在一起。)
JavaMail:在javaweb应用中,我们非常需要电子邮件的功能。sun公司已经为我们准备好了JavaMail技术,专门帮助处理邮件相关。使用JavaMail技术需要在本机安装邮件服务器,本篇博客使用的是Apache Commons Email组件编写,所以对JavaMail不做介绍。
关于邮件发送,我们对相关的协议做基本的了解:
- SMTP( Simple Mail Transfer Protocol ):电子邮件发送协议。当我们使用客户端程序发送邮件时,客户端程序先把邮件发送给我们设置SMTP服务器,然后SMTP服务器再根据收件人的地址,把邮件中转给接受方的SMTP服务器,以便让邮件收件人最终使用POP3或者IMAP方式收取邮件。JavaMail API不包含SMIP的服务程序,所以使用JavaMail技术发送邮件,需要其他SMTP服务器的支持。
- POP3协议(Post Office Protocol V3):是一种收取邮件的协议,通过这个协议,可以让邮件客户端程序把存在POP3服务器上的邮件接收到本机上进行处理。
- IMAP协议(Internet Message Access Protocol):IMAP是更加高级的用于接收邮件的协议。
- MIME协议(Multipurpose Internet Mail Extensions):它不是邮件传输协议,但对传输内容的文本、附件及其他内容定义了格式。
程序开工:
准备工作:此次程序用到的jar文件上传:https://download.csdn.net/download/tobe_coder/10653981
注册一个新浪邮箱,进入设置,——》客户端POP/imap/smtp——》将POP/smtp服务状态开启。
sendAttachmentMail.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>发送邮件</title>
</head>
<body><h3>发送邮件程序</h3>
<%--enctype="multipart/form-data"注意此属性设置,此属性是表单上传文件必不可少的参数--%>
<form action="sendAttachmentMail" method="post" enctype="multipart/form-data">收件人:<input type="text" name="to"/><br>发件人:<input type="text" name="from"/><br>主题:<input type="text" name="topic"><br>添加附件:<input type="file" name="attach"><br>正文:<textarea cols="50" rows="30" name="content"></textarea><br><input type="submit" value="提交"/><input type="reset" value="重置"/>
</form>
</body>
</html>
SendAttachmentMailServlet:
/*** 编写可以发送附件的邮件发送程序* 结合使用邮件发送和文件上传实现*/
@WebServlet(value="/sendAttachmentMail",initParams = {@WebInitParam(name = "savePath",value = "uploads")})
public class SendAttachmentMailServlet extends HttpServlet {private String savePath; //上传文件的存储路径ServletContext application;private Map<String,String> parameters=new HashMap();@Overridepublic void init(ServletConfig config) throws ServletException { //初始化savePath=config.getInitParameter("savePath"); //取到文件的存储路径application=config.getServletContext();//初始化ServletContext}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {request.setCharacterEncoding("utf-8");File file=doAttachment(request);//获取上传的文件try {//此类是能发送带附件邮件的行为MultiPartEmail email=new MultiPartEmail();email.setCharset("utf-8");email.setHostName("smtp.sina.com"); //不要将smtp写成stmpemail.setAuthentication("test@sina.com","123456");email.addTo(parameters.get("to"));email.setFrom(parameters.get("from"));email.setSubject(parameters.get("topic"));email.setMsg(parameters.get("content"));if (file!=null){//如果存在附件EmailAttachment attachment=new EmailAttachment(); //创建一个邮件的附件对象attachment.setPath(file.getPath()); //设置路径到附件attachment.setDescription(EmailAttachment.ATTACHMENT);//附件的描述attachment.setName(file.getName()); //附件的名称email.attach(attachment); //将附件绑定到邮件上}email.send();//邮件发送} catch (EmailException e) {e.printStackTrace();request.setAttribute("sendmail.message","邮件发送不成功");}request.setAttribute("sendmail.message","邮件发送成功");request.getRequestDispatcher("/sendResult.jsp").forward(request,response);}/*** 将文件上传到服务器* @param request* @return*/public File doAttachment(HttpServletRequest request){File file=null;DiskFileItemFactory factory=new DiskFileItemFactory();ServletFileUpload upload=new ServletFileUpload(factory);try {//获取所上传的所有文件和参数的集合对象 from必须要有enctype="multipart/form-data"属性设置,//标记中有"entype"属性,该表单提交之后不能通过request.getParameter("name")取值List items=upload.parseRequest(request);Iterator itr=items.iterator();while(itr.hasNext()){FileItem item= (FileItem) itr.next();if(item.isFormField()){//如果是表单项的情况,将属性和值进行存储parameters.put(item.getFieldName(),item.getString("utf-8"));}else{//如果是file类型的表单if(item.getName()!=null&&!item.getName().equals("")){//item.getName()上传文件在客户端的完整路径名称File tempFile=new File(item.getName());//根据给定的路径名创建一个新的文件实例,ServletContext容器的路径+文件名file=new File(application.getRealPath("/")+savePath,tempFile.getName());item.write(file);}}}} catch (FileUploadException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}return file;}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request, response);}
}
邮件发送成功页面sendResult.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>邮件发送成功页面</title>
</head>
<body><p>${requestScope['sendmail.message']}</p>
<p><a href="sendMail">返回</a></p>
</body>
</html>
程序的相关方法查询api文档:http://tool.oschina.net/apidocs/
相关资源:common-email.jar,fileupload.jar,commons-io.jar包在Apache官网下载。
注:学习的初始阶段,博客比较粗糙。以后细节再补充,如有错误或者疑问,欢迎沟通。