> 文档中心 > 07SpringMVC--文件上传和下载 邮件发送 【工具类】

07SpringMVC--文件上传和下载 邮件发送 【工具类】

目录

JavaWeb

文件上传

jar

【文件上传的注意事项】

【需要用到的类详解】

文件上传需要使用到的3个类+1个属性

Fileltem类

常用方法介绍:

ServletFileUpload 类

代码实现:

jsp页面

servlet

下载文件

SpringMVC  文件上传下载 方式    【工具类】

导入jar包

web.xml

applicatinContext.xml

注册lib

index.jsp  表单

 enctype="multipart/form-data"    一定要配置

applicatinContext.xml   添加文件上传配置 

方式二:

邮件发送

传输协议

4个核心类

发送简单邮件

复杂邮件: 有附件和图片  MIMIE

 复杂邮件 : 图片

 复杂邮件 : 附件  

邮件发送实战

1.index.JSP

2 实体类   序列化Serializable 

3 servlet

4.servlet(绑定路径)

5.发送邮件核心类


JavaWeb

文件上传

jar

              commons-fileupload      commons-fileupload      1.4                  commons-io      commons-io      2.11.0    

【文件上传的注意事项】

1.为保证服务器安全,上传文件应该放在外界无法直接访问的目录下,比如放于WEB-INF目录下。

2.为防止文件覆盖的现象发生,要为上传文件产生一个唯一的文件名 

        【时间戳、加密算法MD5、UUID、位运算】

3.要限制上传文件的最大值。

4.可以限制上传文件的类型,在收到上传文件名时,判断后缀名是否合法。

【需要用到的类详解】

文件上传需要使用到的3个类+1个属性

  • ServletFileUpload:在后端获取文件上传的文件数据,并将上传文件数据的表单中的每个输入项都封装为一个FileItem对象
  • FileItem
  • DiskFileItemFactory:使用ServletFileUpload解析前端表单传过来的文件数据时需要使用到DiskFileItemFactory对象,所以在获取ServletFileUpload对象之前我们需要先获取DiskFileItemFactory对象
  • fileItemFactory属性:ServletFileUpload对象的一个属性

ServletFileUpload负责处理上传的文件数据,并将表单中每个输入项封装成一个Fileltem对象,在使用ServletFileUpload对象解析请求时需要DiskFileltemFactory对象。所以,我们需要在进行解析工作前构造好DiskFileltemFactory对象,通过ServletFileUpload对象的构造方法或setFileltem Factory()方法设置ServletFileUpload对象的fileltemFactory属性。

Fileltem类

1、在HTML页面input必须有name

表单如果包含一个文件上传输入项的话,这个表单的enctype属性就必须设置为multipart/form-data  【必须】

         上传用户: 

常用方法介绍:

//isFormFile方法用于判断FileItem类对象封装的数据是一个普通文本表单//还是一个文件表单,如果时普通表单字段则返回true,否则返回falseboolean isField();//getFieldName方法用于返回表单标签name属性的值String getFieldName();//getString方法用于将FileItem对象中保存的数据流内容以一个字符串返回String getString();//getName方法用于获得文件上传字段中的文件名。String getName();//以流的形式返回上传文件的数据内容。InputStream getInputStream();//delete方法用来清空FileItem类对象中存放的主体内容//如果主体内容被保存在临时文件中,delete方法将删除该临时文件void delete();

ServletFileUpload 类

​ ServletFileUpload负责处理上传的文件数据,并将表单中每个输入项封装成一个FileItem对象中 . 使用其parseRequest(HttpServletRequest) 方法可以将通过表单中每一个HTML标签提交的数据封装成一个FileItem对象,然后以List列表的形式返回,使用该方法处理上传文件简单易用

代码实现:

package com.gh.servlet;/** * @author gh  Email:@2495140780qq.com * @Description * @date 2022-01-06-下午 10:19 */import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.util.List;import java.util.UUID;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.commons.fileupload.FileItem;import org.apache.commons.fileupload.FileUploadException;import org.apache.commons.fileupload.ProgressListener;import org.apache.commons.fileupload.disk.DiskFileItemFactory;import org.apache.commons.fileupload.servlet.ServletFileUpload;/** * Servlet implementation class FileSerlvet */public class FileSerlvet extends HttpServlet {    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws javax.servlet.ServletException, IOException { //判断上传的表单是普通表单还是带文件的表单,是返回true,否返回false; if (!ServletFileUpload.isMultipartContent(request)){     return;//如果这是一个普通文件我们直接返回 }//如果通过了这个if,说明我们的表单是带文件上传的 //创建上传文件的保存目录,为了安全建议在WEB-INF目录下,用户无法访问 String uploadpath = this.getServletContext().getRealPath("WEB-INF/Upload");//获取上传文件的保存路径 File uploadfile = new File(uploadpath); if (!uploadfile.exists()){     uploadfile.mkdir();//如果目录不存在就创建这样一个目录 } //临时文件 //临时路径,如果上传的文件超过预期的大小,我们将它存放到一个临时目录中,过几天自动删除,或者提醒用户转存为永久 String tmppath = this.getServletContext().getRealPath("WEB-INF/tmp"); File file = new File(tmppath); if (!file.exists()){     file.mkdir();//如果目录不存在就创建这样临时目录 } //处理上传的文件一般需要通过流来获取,我们可以通过request.getInputstream(),原生态文件上传流获取,十分麻烦 //但是我们都建议使用Apache的文件上传组件来实现,common-fileupload,它需要依赖于common-io组件; try {     //1、创建DiskFileItemFactory对象,处理文件上传路径或限制文件大小     DiskFileItemFactory factory = gteDiskFileItemFactory(file);     //2、获取ServletFileUpload     ServletFileUpload upload = getServletFileUpload(factory);     //3、处理上传文件     String msg = uploadParseRequest(upload,request,uploadpath);     //Servlet请求转发消息     request.setAttribute("msg",msg);     request.getRequestDispatcher("/info.jsp").forward(request,response); }catch (FileUploadException e){     e.printStackTrace(); }    }    public static DiskFileItemFactory gteDiskFileItemFactory(File file){ //1、创建DiskFileItemFactory对象,处理文件上传路径或限制文件大小 DiskFileItemFactory factory = new DiskFileItemFactory(); //通过这个工厂设置一个缓冲区,当上传的文件大小大于缓冲区的时候,将它放到临时文件中; factory.setSizeThreshold(1024 * 1024);//缓冲区大小为1M factory.setRepository(file); return factory;    }    public static ServletFileUpload getServletFileUpload(DiskFileItemFactory factory){ //2、获取ServletFileUpload ServletFileUpload upload = new ServletFileUpload(factory); //监听文件上传进度 upload.setProgressListener(new ProgressListener() {     public void update(long pBytesRead, long lpContentLenght, int i) {  //pBytesRead:已读取到的文件大小  //pContentLenght:文件大小  System.out.println("总大小:"+lpContentLenght+"已上传:"+pBytesRead);     } }); //处理乱码问题 upload.setHeaderEncoding("UTF-8"); //设置单个文件的最大值 upload.setFileSizeMax(1024 * 1024 * 10); //设置总共能够上传文件的大小 //1024 = 1kb * 1024 = 1M * 10 = 10M upload.setSizeMax(1024 * 1024 * 10); return upload;    }    public static String uploadParseRequest(ServletFileUpload upload,HttpServletRequest request,String uploadpath) throws IOException, FileUploadException { String msg = ""; //3、处理上传文件 //把前端的请求解析,封装成一个FileItem对象 List fileItems = upload.parseRequest(request); for (FileItem fileItem : fileItems) {     if (fileItem.isFormField()){ //判断是普通表单还是带文件的表单  //getFieldName指的是前端表单控件的name  String name = fileItem.getFieldName();  String value = fileItem.getString("UTF-8");//处理乱码  System.out.println(name+":"+value);     }else {//判断它是带文件的表单  //======================处理文件=======================//  //拿到文件的名字  String uploadFileName = fileItem.getName();  System.out.println("上传的文件名:"+uploadFileName);  if (uploadFileName.trim().equals("") || uploadFileName == null){      continue;  }  //获得上传的文件名,例如/img/girl/ooa.jpg,只需要ooa,其前面的后面的都不需要  String fileName = uploadFileName.substring(uploadFileName.lastIndexOf("/") + 1);  //获得文件的后缀名  String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1); /*   如果文件后缀名fileExtName不是我们所需要的   就直接return,不处理,告诉用户文件类型不对*/  //可以使用UUID(唯一识别的通用码),保证文件名唯一  //UUID.randomUUID,随机生一个唯一识别的通用码  //网络传输中的东西,都需要序列化  //pojo,实体类,如果想要在多个电脑运行,传输--->需要吧对象都序列化了  //JNI=java Native Interface  //implements Serializable :标记接口,JVM--->java栈 本地方法栈 native-->c++  String uuidPath= UUID.randomUUID().toString();  System.out.println("文件信息【文件名:"+fileName+"文件类型:"+fileExtName+"】");  //可以使用UUID(唯一通用识别码)来保证文件名的统一  String uuidFileName = UUID.randomUUID().toString();  //=======================传输文件=========================//  //获得文件上传的流  InputStream inputStream = fileItem.getInputStream();  //创建一个文件输出流  FileOutputStream fos = new FileOutputStream(uploadpath + "/" + uuidFileName +"."+ fileExtName);  //创建一个缓冲区  byte[] buffer = new byte[1024 * 1024];  //判断是否读取完毕  int len = 0;  //如果大于0,说明还存在数据  while ((len=inputStream.read(buffer))>0){      fos.write(buffer,0,len);  }  //关闭流  fos.close();  inputStream.close();  msg = "文件上传成功!";  fileItem.delete();//上传成功,清除临时文件     } } return msg;    }}

jsp页面

    Title    上传用户: 

|

info.jsp 

    Title${msg}

servlet

     FileServlet com.hao.servlet.FileServlet         FileServlet /upload.do    

下载文件

  1. 向浏览器输出消息

  2. 下载文件

    1. 要获取下载文件的路径

    2. 下载的文件名是啥?

    3. 设置想办法让浏览器(Content-Disposition)能够支持下载我们需要的东西

    4. 获取下载文件的输入流

      Io

    5. 创建缓冲区

    6. 获取OutputStream对象

    7. 将FileOutputStream流写入到buffer缓冲区

    8. 使用OutputStream将缓冲区中的数据输出到客户端!

public class FileServlet extends HttpServlet {    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1. 要获取下载文件的路径 String realPath = "/G:\\JavaWeb-Servlet\\03-response\\target\\03-response\\WEB-INF\\classes\\1.jpg"; //2. 下载的文件名是啥 //方法:截取路径 / 后面的文件名 String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1); //3. 设置想办法让浏览器(Content-Disposition)能够支持下载我们需要的东西,中文文件名URLEncoder.encode编码,否则有可能乱码 //网上搜索:web下载文件的头 resp.setHeader("Content-disposition","attachment;filename="+ URLEncoder.encode(fileName,"UTF-8")); //4. 获取下载文件的输入流 FileInputStream in = new FileInputStream(realPath); //5. 创建缓冲区 int len = 0; byte[] buffer = new byte[1024]; //6. 获取OutputStream对象 ServletOutputStream out = resp.getOutputStream(); //7. 将FileOutputStream流写入到buffer缓冲区   //8. 使用OutputStream将缓冲区中的数据输出到客户端 while((len = in.read(buffer)) != -1) {     out.write(buffer, 0, len); } in.close(); out.close();    }    @Override    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp);    }}

SpringMVC  文件上传下载 方式    【工具类】

                只需要更改下载的文件的位置即可

创建项目

导入jar包

           commons-fileupload     commons-fileupload     1.4        javax.servlet     javax.servlet-api     4.0.1     

web.xml

         springmvc org.springframework.web.servlet.DispatcherServlet      contextConfigLocation     classpath:springmvc-servlet.xml  1         springmvc /             encoding org.springframework.web.filter.CharacterEncodingFilter      encoding     utf-8              encoding /*    

applicatinContext.xml

                                        

注册lib

index.jsp  表单

 enctype="multipart/form-data"    一定要配置

      $Title$                          

applicatinContext.xml   添加文件上传配置 

               

CommonsMultipartFile 的 常用方法:

  • String getOriginalFilename():获取上传文件的原名

  • InputStream getInputStream():获取文件流

  • void transferTo(File dest):将上传文件保存到一个目录文件中

方式一

@Controllerpublic class FileController {    //@RequestParam("file") 将name=file控件得到的文件封装成CommonsMultipartFile 对象    //批量上传CommonsMultipartFile则为数组即可    @RequestMapping("/upload")    public String fileUpload(@RequestParam("file") CommonsMultipartFile file , HttpServletRequest request) throws IOException { //获取文件名 : file.getOriginalFilename(); String uploadFileName = file.getOriginalFilename(); //如果文件名为空,直接回到首页! if ("".equals(uploadFileName)){     return "redirect:/index.jsp"; } System.out.println("上传文件名 : "+uploadFileName); //上传路径保存设置 String path = request.getServletContext().getRealPath("/upload"); //如果路径不存在,创建一个 File realPath = new File(path); if (!realPath.exists()){     realPath.mkdir(); } System.out.println("上传文件保存地址:"+realPath); InputStream is = file.getInputStream(); //文件输入流 OutputStream os = new FileOutputStream(new File(realPath,uploadFileName)); //文件输出流 //读取写出 int len=0; byte[] buffer = new byte[1024]; while ((len=is.read(buffer))!=-1){     os.write(buffer,0,len);     os.flush(); } os.close(); is.close(); return "redirect:/index.jsp";    }}

方式二  【推荐】

采用file.Transto 来保存上传的文件

/** 采用file.Transto 来保存上传的文件*/@RequestMapping("/upload2")public String  fileUpload2(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException {   //上传路径保存设置   String path = request.getServletContext().getRealPath("/upload");   File realPath = new File(path);   if (!realPath.exists()){realPath.mkdir();  }   //上传文件地址   System.out.println("上传文件保存地址:"+realPath);   //通过CommonsMultipartFile的方法直接写文件(注意这个时候)   file.transferTo(new File(realPath +"/"+ file.getOriginalFilename()));   return "redirect:/index.jsp";}

文件下载步骤:

方式一:

1、设置 response 响应头

2、读取文件 -- InputStream

3、写出文件 -- OutputStream

4、执行操作

5、关闭流 (先开后关)

代码实现:

    /*    * 文件下载    * */    @RequestMapping(value="/download")    public String downloads(HttpServletResponse response ,HttpServletRequest request) throws Exception{ //要下载的图片地址 String  path = request.getServletContext().getRealPath("/upload"); String  fileName = "基础语法.jpg"; //1、设置response 响应头 response.reset(); //设置页面不缓存,清空buffer response.setCharacterEncoding("UTF-8"); //字符编码 response.setContentType("multipart/form-data"); //二进制传输数据 //设置响应头 response.setHeader("Content-Disposition",  "attachment;fileName="+ URLEncoder.encode(fileName, "UTF-8")); File file = new File(path,fileName); //2、 读取文件--输入流 InputStream input=new FileInputStream(file); //3、 写出文件--输出流 OutputStream out = response.getOutputStream(); byte[] buff =new byte[1024]; int index=0; //4、执行 写出操作 while((index= input.read(buff))!= -1){     out.write(buff, 0, index);     out.flush(); } out.close(); input.close(); return null;    }

前端

  点击下载

方式二:

        a链接设置请求头

  点击下载

邮件发送

        要在网络上实现邮件功能,必须要有专门的邮件服务器

传输协议

SMTP协议

发送邮件:

我们通常把处理用户smtp请求(邮件发送请求)的服务器称之为SMTP服务器(邮件发送服务器)。

POP3协议

接收邮件

我们通常把处理用户pop3请求(邮件接收请求)的服务器称之为POP3服务器(邮件接收服务器)。

使用Java发送E-mail十分简单,但是首先你应该准备JavaMail APIJava Activation Framework。

得到两个jar包:

                • mail.jar

                • activation.jar

    javax.mail    mail    1.4.7    javax.activation    activation    1.1.1

4个核心类

1.创建session对象
2.创建Transport对象
3.使用邮箱的用户名和授权码连上邮件服务器
4.创建一个Message对象(需要传递session)
message需要指明发件人、收件人以及文件内容
5.发送邮件
6.关闭连接

发送简单邮件

package com.gh;import com.sun.mail.util.MailSSLSocketFactory;import javax.mail.*;import javax.mail.internet.InternetAddress;import javax.mail.internet.MimeMessage;import java.security.GeneralSecurityException;import java.util.Properties;/** * @author gh  Email:@2495140780qq.com * @Description * @date 2022-01-20-下午 8:36 *///发送简单邮件public class MailDemo01 {    public static void main(String[] args) throws Exception { Properties prop=new Properties(); prop.setProperty("mail.host","smtp.qq.com");///设置QQ邮件服务器 prop.setProperty("mail.transport.protocol","smtp");///邮件发送协议 prop.setProperty("mail.smtp.auth","true");//需要验证用户密码 //QQ邮箱需要设置SSL加密  其他邮箱不需要  大厂 MailSSLSocketFactory sf=new MailSSLSocketFactory(); sf.setTrustAllHosts(true); prop.put("mail.smtp.ssl.enable","true"); prop.put("mail.smtp.ssl.socketFactory",sf); //使用javaMail发送邮件的5个步骤 //1.创建定义整个应用程序所需要的环境信息的session对象 // qq才有 其他邮箱没有 Session session=Session.getDefaultInstance(prop, new Authenticator() {     @Override     protected PasswordAuthentication getPasswordAuthentication() {  return new PasswordAuthentication("XXXX@qq.com","授权码");     } }); //开启session的debug模式,这样可以查看到程序发送Email的运行状态  【可选】 session.setDebug(true); //2.通过session得到transport对象 Transport ts=session.getTransport(); //3.使用邮箱的用户名和授权码连上邮件服务器 ts.connect("smtp.qq.com","XXXX@qq.com","授权码"); //4.创建邮件:写邮件 //注意需要传递session MimeMessage message=new MimeMessage(session); //指明邮件的发件人 message.setFrom(new InternetAddress("XXXX@qq.com")); //指明邮件的收件人 message.setRecipient(Message.RecipientType.TO,new InternetAddress("XXXX@qq.com")); //邮件标题 message.setSubject("发送的标题"); //邮件的文本内容 message.setContent("内容","text/html;charset=UTF-8"); //5.发送邮件 ts.sendMessage(message,message.getAllRecipients()); //6.关闭连接 ts.close();    }}

复杂邮件: 有附件和图片  MIMIE

MIME(多用途互联网邮件扩展类型)

MimeBodyPart类

javax.mail.internet.MimeBodyPart类表示的是一个MIME消息,它和MimeMessage类一样都是从Part接口继承过来。

MimeMultipart类

javax.mail.internet.MimeMultipart是抽象类Multipart的实现子类,它用来组合多个MIME消息。一个MimeMultipart对象可以包含多个代表MIME消息的MimeBodyPart对象。

 复杂邮件 : 图片

import com.sun.mail.util.MailSSLSocketFactory;import javax.activation.DataHandler;import javax.activation.FileDataSource;import javax.mail.*;import javax.mail.internet.InternetAddress;import javax.mail.internet.MimeBodyPart;import javax.mail.internet.MimeMessage;import javax.mail.internet.MimeMultipart;import java.util.Properties;//复杂邮件 : 图片public class MailDemo02 {    public static void main(String[] args) throws Exception { Properties prop=new Properties(); prop.setProperty("mail.host","smtp.qq.com");///设置QQ邮件服务器 prop.setProperty("mail.transport.protocol","smtp");///邮件发送协议 prop.setProperty("mail.smtp.auth","true");//需要验证用户密码 //QQ邮箱需要设置SSL加密  其他邮箱不需要  大厂 MailSSLSocketFactory sf=new MailSSLSocketFactory(); sf.setTrustAllHosts(true); prop.put("mail.smtp.ssl.enable","true"); prop.put("mail.smtp.ssl.socketFactory",sf); //使用javaMail发送邮件的5个步骤 //1.创建定义整个应用程序所需要的环境信息的session对象 // qq才有 其他邮箱没有 Session session=Session.getDefaultInstance(prop, new Authenticator() {     @Override     protected PasswordAuthentication getPasswordAuthentication() {  return new PasswordAuthentication("XXXX@qq.com","授权码");     } }); //开启session的debug模式,这样可以查看到程序发送Email的运行状态  【可选】 session.setDebug(true); //2.通过session得到transport对象 Transport ts=session.getTransport(); //3.使用邮箱的用户名和授权码连上邮件服务器 ts.connect("smtp.qq.com","XXXX@qq.com","授权码"); //4.创建邮件:写邮件 //注意需要传递session MimeMessage message=new MimeMessage(session); //指明邮件的发件人 message.setFrom(new InternetAddress("XXXX@qq.com")); //指明邮件的收件人 message.setRecipient(Message.RecipientType.TO,new InternetAddress("XXXX@qq.com")); //邮件标题 message.setSubject("发送的标题"); /* * 邮件的文本内容    扩充 * message.setContent("内容","text/html;charset=UTF-8"); */ //=================================准备图片数据======================================= MimeBodyPart image = new MimeBodyPart(); //图片需要经过数据化的处理  DataHandler 数据处理 DataHandler dh = new DataHandler(new FileDataSource("G:\\JavaWeb-Servlet\\10-mail\\src\\4.png")); //在part中放入这个处理过图片的数据 image.setDataHandler(dh);  //在我们的body 中放入这个处理的图片数据 //给这个part设置一个ID名字 image.setContentID("bz.jpg"); //准备正文的数据 MimeBodyPart text = new MimeBodyPart(); //src='cid:bz.jpg'  固定  对应上面     image.setContentID("bz.jpg"); 中setContentID text.setContent("这是一张正文", "text/html;charset=UTF-8"); //描述数据关系 MimeMultipart mm = new MimeMultipart(); mm.addBodyPart(text); mm.addBodyPart(image); mm.setSubType("related"); //设置到消息中,保存修改 message.setContent(mm);  //把最后编辑好的邮件放到消息当中 message.saveChanges();   //保存修改 //======================================================================== //5.发送邮件 ts.sendMessage(message, message.getAllRecipients()); //6.关闭连接 ts.close();    }}

 复杂邮件 : 附件  

import com.sun.mail.util.MailSSLSocketFactory;import javax.activation.DataHandler;import javax.activation.FileDataSource;import javax.mail.*;import javax.mail.internet.*;import java.util.Properties;复杂邮件 : 附件public class MailDemo03 {    public static void main(String[] args) throws Exception { Properties prop=new Properties(); prop.setProperty("mail.host","smtp.qq.com");///设置QQ邮件服务器 prop.setProperty("mail.transport.protocol","smtp");///邮件发送协议 prop.setProperty("mail.smtp.auth","true");//需要验证用户密码 //QQ邮箱需要设置SSL加密 MailSSLSocketFactory sf=new MailSSLSocketFactory(); sf.setTrustAllHosts(true); prop.put("mail.smtp.ssl.enable","true"); prop.put("mail.smtp.ssl.socketFactory",sf); //使用javaMail发送邮件的5个步骤 //1.创建定义整个应用程序所需要的环境信息的session对象 Session session=Session.getDefaultInstance(prop, new Authenticator() {     @Override     protected PasswordAuthentication getPasswordAuthentication() {  return new PasswordAuthentication("1192XXXX@qq.com","授权码");     } }); //开启session的debug模式,这样可以查看到程序发送Email的运行状态 session.setDebug(true); //2.通过session得到transport对象 Transport ts=session.getTransport(); //3.使用邮箱的用户名和授权码连上邮件服务器 ts.connect("smtp.qq.com","1192XXXX@qq.com","授权码"); //4.创建邮件:写文件 //注意需要传递session MimeMessage message=new MimeMessage(session); //指明邮件的发件人 message.setFrom(new InternetAddress("1192XXXX@qq.com")); //指明邮件的收件人 message.setRecipient(Message.RecipientType.TO,new InternetAddress("1192XXXX@qq.com")); //邮件标题 message.setSubject("java发出"); //邮件的文本内容 //=================================准备图片数据 MimeBodyPart image=new MimeBodyPart(); //图片需要经过数据化的处理 DataHandler dh = new DataHandler(new FileDataSource("G:\\JavaWeb-Servlet\\10-mail\\src\\4.png")); //在part中放入这个处理过图片的数据 image.setDataHandler(dh); //给这个part设置一个ID名字 image.setContentID("bz.jpg"); //=================================准备正文数据 MimeBodyPart text=new MimeBodyPart(); text.setContent("这是一张正文","text/html;charset=UTF-8"); //=================================准备附件数据 MimeBodyPart body1= new MimeBodyPart(); body1.setDataHandler(new DataHandler(new FileDataSource("G:\\JavaWeb-Servlet\\10-mail\\src\\1.txt"))); body1.setFileName("1.txt"); //描述数据关系 MimeMultipart mm=new MimeMultipart(); mm.addBodyPart(body1); mm.addBodyPart(text); mm.addBodyPart(image); mm.setSubType("mixed"); //设置到消息中,保存修改 message.setContent(mm); message.saveChanges(); //5.发送邮件 ts.sendMessage(message,message.getAllRecipients()); //6.关闭连接 ts.close();    }}

邮件发送实战

1.index.JSP

Hello World!

用户名: 密码: 邮箱:

2 实体类   序列化Serializable 

import java.io.Serializable;/** * @author gh  Email:@2495140780qq.com * @Description * @date 2022-01-20-下午 9:53 */public class User implements Serializable {    private String username;    private String password;    private String email;    public User() {    }    public User(String username, String password, String email) { this.username = username; this.password = password; this.email = 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;    }    @Override    public String toString() { return "User{" +  "username='" + username + '\'' +  ", password='" + password + '\'' +  ", email='" + email + '\'' +  '}';    }}

3 servlet

import com.gh.pojo.User;import com.gh.utils.Sendmail;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;/** * @author gh  Email:@2495140780qq.com * @Description * @date 2022-01-20-下午 10:00 */public class RegisterServlet extends HttpServlet {    @Override    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //接收用户数据,封装成对象 String username=req.getParameter("username"); String password=req.getParameter("pwd"); String email=req.getParameter("email"); User user=new User(username,password,email); //用户注册成功之后,给用户发送一封邮件 //我们使用线程来专门发送邮件。防止出现耗时,和网站注册人数过多的情况 Sendmail send=new Sendmail(user); //启动线程,线程启动之后就会执行run方法来发送邮件 send.start(); //祖册用户 req.setAttribute("message", "注册成功,我们已经发送了一封邮件,请查收!网络不稳定,可能过会才能收到!!!"); req.getRequestDispatcher("info.jsp").forward(req, resp);    }    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp);    }}

4.servlet(绑定路径)

     RegisterServlet com.gh.servlet.RegisterServlet         RegisterServlet /RegisterServlet.do    

5.发送邮件核心类

package com.gh.utils;import com.gh.pojo.User;import com.sun.mail.util.MailSSLSocketFactory;import javax.mail.*;import javax.mail.internet.InternetAddress;import javax.mail.internet.MimeMessage;import java.util.Properties;/** * @author gh  Email:@2495140780qq.com * @Description * @date 2022-01-20-下午 10:00 *///   网址3秒原则 : 用户体验//   多线程实现用户体验  (异步处理)public class Sendmail extends Thread {    //用于给用户发送邮件的邮箱    private String from = "XXXX@qq.com";    //邮箱的用户名     private String username = "XXX@qq.com";    // 邮箱的密码  授权码     private String password = "XXX";    //发送邮件的服务器地址    private String host="smtp.qq.com";    private User user;    public Sendmail(User user){ this.user=user;    }    //重写run实现方法的实现,在run方法中实现邮件给制定的用户    @Override    public void run() { try {     Properties prop=new Properties();     prop.setProperty("mail.host",host);///设置QQ邮件服务器     prop.setProperty("mail.transport.protocol","smtp");///邮件发送协议     prop.setProperty("mail.smtp.auth","true");//需要验证用户密码     //QQ邮箱需要设置SSL加密     MailSSLSocketFactory sf=new MailSSLSocketFactory();     sf.setTrustAllHosts(true);     prop.put("mail.smtp.ssl.enable","true");     prop.put("mail.smtp.ssl.socketFactory",sf);     //使用javaMail发送邮件的5个步骤     //1.创建定义整个应用程序所需要的环境信息的session对象     Session session= Session.getDefaultInstance(prop, new Authenticator() {  @Override  protected PasswordAuthentication getPasswordAuthentication() {      return new PasswordAuthentication(from,password);//授权码  }     });     //开启session的debug模式,这样可以查看到程序发送Email的运行状态     session.setDebug(true);     //2.通过session得到transport对象     Transport ts=session.getTransport();     //3.使用邮箱的用户名和授权码连上邮件服务器     ts.connect(host,from,password);//授权码     //4.创建邮件:写文件     //注意需要传递session     MimeMessage message=new MimeMessage(session);     //指明邮件的发件人     message.setFrom(new InternetAddress(from));     //指明邮件的收件人     message.setRecipient(Message.RecipientType.TO,new InternetAddress(user.getEmail()));     //邮件标题     message.setSubject("注册通知");     //邮件的文本内容     message.setContent("恭喜你("+user.getUsername()+")成功注册!"+"密码:"+user.getPassword() + "请妥善保管你的密码,不要让他人知道"      ,"text/html;charset=UTF-8");     //5.发送邮件     ts.sendMessage(message,message.getAllRecipients());     //6.关闭连接     ts.close(); }catch (Exception e){     System.out.println(e); }    }}

这里引入多线程的目的是为了提高用户的体验,防止因发送文件时间过长,导致前端响应过久,因此这里采用异步响应。