目标:实现一个基于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();
@Override
public 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写成stmp
email.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官网下载。
注:学习的初始阶段,博客比较粗糙。以后细节再补充,如有错误或者疑问,欢迎沟通。
&spm=1001.2101.3001.5002&articleId=82530260&d=1&t=3&u=394b4be7b7f541f2a6d18e08c8790929)
1036

被折叠的 条评论
为什么被折叠?



