Java(JavaWeb07)

本文档详细介绍了在JavaWeb中如何实现文件上传和邮件发送。文件上传部分讲解了使用Apache的common-fileupload组件处理文件流,设置上传路径、限制文件大小和类型。邮件发送部分涉及SMTP和POP3协议,展示了使用JavaMail发送纯文本、带图片邮件的代码,并讨论了在非Web项目和SpringBoot中发送邮件的方法。

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

Java(JavaWeb07)

参考视频:38. 文件传输原理及介绍(狂神)

16. JavaWeb实现文件上传

16.1 准备工作

  • 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的。
  • 一般采用Apache的开源工具common-fileupload这个文件上传组件。
  • common-fileupload是依赖于common-io这个包的,所以还需要下载这个包。
    • common-io: https://mvnrepository.com/artifact/commons-io/commons-io/2.6
    • common-fileupload: https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload/1.4

  • 在JavaWeb项目中导入jar包:

16.2 使用类介绍

【文件上传注意事项】

  1. 为保证服务器的安全,上传的文件应放在外界无法访问的目录下,如WEN-INF。
  2. 为防止同名文件产生覆盖现象,要为文件指定一个唯一的文件名。
  3. 要对上传文件的大小进行限制。
  4. 限制上传文件的类型,收到文件时,判断文件名十分合法。

【需要用到的类详解】

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

FileItem类

  • 在HTML页面中必须要有name <input type="file" name="filename>"

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

  • 问题:

    • 如果new 不出Servlet,要添加Tomcat中的jar包。
    • 项目可能出问题,点Fix修复。
      在这里插入图片描述

16.3 文件上传代码

  • info.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

${msg}

</body>
</html>
  • index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>$Title$</title>
</head>
<body>

<%--通过表单上传文件
    get: 上传文件大小限制
    post: 没限制
--%>
<%--${pageContext.request.contextPath}获取服务器路径--%>
<form action="${pageContext.request.contextPath}/upload.do" enctype="multipart/form-data" method="post">
    上传用户:<input type="text" name="username"><br>
    <p><input type="file" name="file1"></p>
    <p><input type="file" name="file2"></p>

    <p><input type="submit"> | <input type="reset"></p>
</form>

</body>
</html>
  • web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
	
	<servlet>
		<servlet-name>FileServlet</servlet-name>
		<servlet-class>com.zach.servlet.FileServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>FileServlet</servlet-name>
		<url-pattern>/upload.do</url-pattern>
	</servlet-mapping>
	
</web-app>
  • FileServlet
package com.zach.servlet;

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;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.UUID;

/**
 * @author : Zach
 * @date : 2022-06-16 11:44
 * @description :
 * @modified by :
 */

public class FileServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) {}
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        
        //判断上传的文件是普通表单还是带文件的表单
        if (!ServletFileUpload.isMultipartContent(req)){
            return;//终止方法运行,说明这是一个普通的表单,直接返回。
        }
        
        //创建上传文件的保存路径,建议在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 tmpFile = new File(tmpPath);
        if (!tmpFile.exists()){
            tmpFile.mkdir();//创建这个临时目录
        }
        
        //处理上传的文件,一般都需要通过流来获取,我们可以使用request.getInputStream(),原生态的文件上传流获取,十分麻烦。
        //但是我们都建议使用Apache的文件上传组件来实现,common-fileupload,他需要依赖于commons-io组件。
    
        //以下为复制的
        //1.创建DiskFileItemFactory对象,处理文件路径上传或者大小限制的
        DiskFileItemFactory factory = createDiskFileItemFactory(tmpFile);
        //2.获取ServletFileUpload
        ServletFileUpload upload = creatServletFileUpload(factory);
        //3.处理上传的文件
        String msg = uploadFile(req, uploadPath, upload);
    
        //转发
        req.setAttribute("msg", msg);
        req.getRequestDispatcher("/info.jsp").forward(req, resp);
        
    }
    
    private String uploadFile(HttpServletRequest req, String uploadPath, ServletFileUpload upload) throws IOException {
        String msg = "";
        //把前端请求解析,封装成一个FileItem对象,需要从ServletFileUpload对象中获取
        try {
            List<FileItem> fileItems = upload.parseRequest(req);
            for (FileItem fileItem : fileItems) {
                if (fileItem.isFormField()) {
                    String fieldName = fileItem.getFieldName();
                    //处理乱码
                    String value = fileItem.getString("UTF-8");
                    System.out.println(fieldName + ":" + value);
                } else {
                    //文件
                    //===========处理文件============
                    String uploadFileName = fileItem.getName();
                    System.out.println("uploadFileName:" + uploadFileName);
                    //可能存在文件名不合法的情况
                    if (uploadFileName == null || "".equals(uploadFileName.trim())) {
                        continue;
                    }
                    //获取上传的文件名
                    String fileName = uploadFileName.substring(uploadFileName.lastIndexOf("/") + 1);
                    //获取文件的后缀名
                    String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1);
                    //如果文件后缀名fileExtName不是我们所需要的,就直接return,不处理,告诉用户文件类型不对
                    
                    //可以使用UUID(统一识别的通用码),保证文件名唯一
                    //UUID.randomUUID() 随机生一个唯一识别的通用码
                    //网络从传输中的东西,都需要序列化
                    //implements java.io.Serializable 标记接口  本地方法栈--》C++
                    String uuidPath = UUID.randomUUID().toString();
                    
                    //===========存放地址============
                    String realPath = uploadPath + "/" + uuidPath;
                    File realPathFile = new File(realPath);
                    if (!realPathFile.exists()) {
                        realPathFile.mkdir();
                    }
                    //===========文件传输============
                    InputStream inputStream = fileItem.getInputStream();
                    FileOutputStream fos = new FileOutputStream(realPath + "/" + fileName);
                    byte[] buffer = new byte[1024 * 1024];
                    int len = 0;
                    while ((len = inputStream.read(buffer)) > 0) {
                        fos.write(buffer, 0, len);
                    }
                    fos.close();
                    inputStream.close();
                    msg = "上传成功~";
                }
            }
        } catch (FileUploadException e) {
            e.printStackTrace();
            msg = "上传失败~";
        }
        return msg;
    }
    
    private ServletFileUpload creatServletFileUpload(DiskFileItemFactory factory) {
        ServletFileUpload upload = new ServletFileUpload(factory);
        //监听文件上传进度
        upload.setProgressListener(new ProgressListener() {
            /**
             *
             * @param pBytesRead 已经读取到的文件大小
             * @param pContentLength 文件总大小
             * @param pItems
             */
            @Override
            public void update(long pBytesRead, long pContentLength, int pItems) {
                System.out.println("总大小:" + pContentLength + "已经上传:" + pBytesRead);
            }
        });
        //处理乱码问题
        upload.setHeaderEncoding("UTF-8");
        //设置单个文件的最大值
        upload.setFileSizeMax(1024 * 1024 * 10);
        //设置总共能够上传文件的大小
        //1020 = 1kb * 1024 = 1M * 10 = 10M
        upload.setSizeMax(1024 * 1024 * 10);
        return upload;
    }
    
    private DiskFileItemFactory createDiskFileItemFactory(File tmpFile) {
        DiskFileItemFactory factory = new DiskFileItemFactory();
        //通过这个工厂设置一个缓冲区,当上传的文件大于这个缓冲区的时候,将他放到临时文件中
        //缓冲区大小为1M
        factory.setSizeThreshold(1024 * 1024);
        //临时目录的保存目录
        factory.setRepository(tmpFile);
        return factory;
    }
    
}

17. JavaWeb实现邮件发送

17.1 介绍和原理

  • 要在网络上实现邮件功能,必须要有专门的邮件服务器
  • 这些邮件服务器类似于现实生活中的邮局,它主要负责接收用户投递过来的邮件,并把邮件投递到邮件接收者的电子邮箱中。
  • SMTP服务器地址一般是:smtp.xxx.com,比如163邮箱是smtp.163.com,qq邮箱是smtp.qq.com.
  • 电子邮箱(E-Mail地址)的获得需要在邮件服务器上进行申请。比如我们要使用QQ邮箱,就需要开通邮箱功能。

  • 传输协议
    • SMTP协议
    • 发送邮件:
      • 我们通常把处理用户smtp请求(邮件发送请求)的服务器称之为SMTP服务器(邮件发送服务器)。
    • POP3协议
    • 接收邮件:
      • 我们通常把处理用户pop3请求(邮件接收请求)的服务器称之为POP3服务器(邮件接收服务器)。

  • 邮件收发原理
    在这里插入图片描述
  1. 大狂神通过smtp协议连接到Smtp服务器,然后发送一封邮件给网易的邮件服务器
  2. 网易分析发现需要去QQ的邮件服务器,通过smtp协议将邮件转投给QQ的Smtp服务器
  3. QQ将接收到的邮件存储在24736743@qq.com这个邮件账号的空间中
  4. 小狂神通过Pop3协议连接到Pop3服务器收取邮件
  5. 24736743@qq.com这个邮件账号的空间中取出邮件
  6. Pop3服务器将取出来的邮件送到小狂神手中
  • 【注意】有可能你收件人地址,发件人地址等信息都正确了,控制台也打印了正确的信息,但是在收件箱就是收不到信息。这是因为可能收件箱服务器拒收了你发的邮件(比如认为你的邮件是广告),这时候可能在垃圾箱里能找到,可能找不到。解决办法是重复的邮件内容不要多次发送,或者更换收件箱试试。

在这里插入图片描述

17.2 邮件发送的代码

  • 导入两个jar包
    • mail.jar mail-1.4.7.jar
    • activation.jar activation-1.1.1.jar
  • QQ邮箱授权码在QQ邮箱设置中获取。(要开启POP3/SMTP服务)

  • MailDemo01 (纯文本发送邮件)
package com.zach;

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;

//发送一封简单的邮件
public class MailDemo01 {
    public static void main(String[] args) throws GeneralSecurityException, MessagingException {
    
        Properties properties = new Properties();
        properties.setProperty("mail.host", "smtp.qq.com");//设置QQ邮件服务器
        properties.setProperty("mail.transport.protocol", "smtp");//邮件发送协议
        properties.setProperty("mail.smtp.auth", "true");//需要验证用户名密码
    
        //关于QQ邮箱,还需要设置SSL加密,加上以下以下代码即可
        MailSSLSocketFactory sf = new MailSSLSocketFactory();
        sf.setTrustAllHosts(true);
        properties.put("mail.smtp.ssl.enable", "true");
        properties.put("mail.smtp.ssl.socketFactory", sf);
    
        //使用javaMail发送邮件的5个步骤:
        //1. 创建定义整个应用程序所需的环境信息的Session对象
        Session session = Session.getDefaultInstance(properties, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                //发件人邮件用户名、授权码
                return new PasswordAuthentication("525266345@qq.com", "授权码");
            }
        });
        //--开启debug模式,这样就可以查看到程序发送email的运行状态
        session.setDebug(true);
        
        //2. 通过session得到transport对象
        Transport ts = session.getTransport();
        //3. 使用邮箱的用户名和授权码连上邮件服务器
        ts.connect("smtp.qq.com", "525266345@qq.com", "授权码");
        //4. 创建邮件
        MimeMessage message = new MimeMessage(session);
            //--邮件的发件人
        message.setFrom(new InternetAddress("525266345@qq.com"));
            //--邮件的收件人
        message.setRecipient(Message.RecipientType.TO, new InternetAddress("525266345@qq.com"));
            //--邮件的标题
        message.setSubject("Hello...");
            //--邮件的文本内容
        message.setContent("<h1 style='color: red'>你好...</h1>", "text/html;charset=UTF-8");
        //5. 发送邮件
        ts.sendMessage(message, message.getAllRecipients());
        //6.关闭连接
        ts.close();
    }
    
}
  • MailDemo01 (发送文本+图片)
package com.zach;

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.security.GeneralSecurityException;
import java.util.Properties;

//发送一封简单的邮件
public class MailDemo01 {
    public static void main(String[] args) throws GeneralSecurityException, MessagingException {
    
        Properties properties = new Properties();
        properties.setProperty("mail.host", "smtp.qq.com");//设置QQ邮件服务器
        properties.setProperty("mail.transport.protocol", "smtp");//邮件发送协议
        properties.setProperty("mail.smtp.auth", "true");//需要验证用户名密码
    
        //关于QQ邮箱,还需要设置SSL加密,加上以下以下代码即可
        MailSSLSocketFactory sf = new MailSSLSocketFactory();
        sf.setTrustAllHosts(true);
        properties.put("mail.smtp.ssl.enable", "true");
        properties.put("mail.smtp.ssl.socketFactory", sf);
    
        //使用javaMail发送邮件的5个步骤:
        //1. 创建定义整个应用程序所需的环境信息的Session对象
        Session session = Session.getDefaultInstance(properties, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                //发件人邮件用户名、授权码
                return new PasswordAuthentication("525266345@qq.com", "授权码");
            }
        });
        //--开启debug模式,这样就可以查看到程序发送email的运行状态
        session.setDebug(true);
        
        //2. 通过session得到transport对象
        Transport ts = session.getTransport();
        //3. 使用邮箱的用户名和授权码连上邮件服务器
        ts.connect("smtp.qq.com", "525266345@qq.com", "授权码");
        //4. 创建邮件
        MimeMessage message = new MimeMessage(session);
            //--邮件的发件人
        message.setFrom(new InternetAddress("525266345@qq.com"));
            //--邮件的收件人
        message.setRecipient(Message.RecipientType.TO, new InternetAddress("525266345@qq.com"));
            //--邮件的标题
        message.setSubject("Hello...");
            //--邮件的文本内容
            //message.setContent("<h1 style='color: red'>你好...</h1>", "text/html;charset=UTF-8");

        //==================================================
        //准备 图片 数据
        MimeBodyPart image = new MimeBodyPart();
            //图片需要经过数据处理...  DataHandler
        DataHandler dh = new DataHandler(new FileDataSource("C:\\Users\\Administrator\\IdeaProjects\\JavaWeb\\功能扩展\\mail-java\\src\\1.png"));
        image.setDataHandler(dh);//在我们的Body中放入这个处理的图片数据
            //给图片设置一个id
        image.setContentID("bz.jpg");
    
        //准备 文本 数据
        MimeBodyPart text = new MimeBodyPart();//ContentID=cid
        text.setContent("这是一封邮件带图片<img src='cid:bz.jpg'/>的邮件","text/html;charset=UTF-8");
        
        //描述数据关系:整合
        MimeMultipart mm = new MimeMultipart();
        mm.addBodyPart(text);
        mm.addBodyPart(image);
        mm.setSubType("related");//最高是mixed
    
        //设置到消息中,保存修改
        message.setContent(mm);//把最后编辑好的邮件放到消息中
        message.saveChanges();//保存修改
        //==================================================
        
        //5. 发送邮件
        ts.sendMessage(message, message.getAllRecipients());
        //6.关闭连接
        ts.close();
    }
    
}

18. 网站注册发送邮件实现

  • 简单邮件:没有附件和图片,纯文本邮件
  • 复杂邮件:有附件和图片
  • 要发送邮件,需要获得协议和支持!才能开启服务:POP3/SMTP服务
  • 在QQ邮箱中获取授权码:可以有多个,此处不展示。

  1. MailDemo01 (在非Web的Java项目中)
package com.zach;

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.security.GeneralSecurityException;
import java.util.Properties;

//发送一封简单的邮件
public class MailDemo01 {
    public static void main(String[] args) throws GeneralSecurityException, MessagingException {
    
        Properties properties = new Properties();
        properties.setProperty("mail.host", "smtp.qq.com");//设置QQ邮件服务器
        properties.setProperty("mail.transport.protocol", "smtp");//邮件发送协议
        properties.setProperty("mail.smtp.auth", "true");//需要验证用户名密码
    
        //关于QQ邮箱,还需要设置SSL加密,加上以下以下代码即可
        //MailSSLSocketFactory sf = new MailSSLSocketFactory();
        //sf.setTrustAllHosts(true);
        //properties.put("mail.smtp.ssl.enable", "true");
        //properties.put("mail.smtp.ssl.socketFactory", sf);
    
        //使用javaMail发送邮件的5个步骤:
        //1. 创建定义整个应用程序所需的环境信息的Session对象
        Session session = Session.getDefaultInstance(properties, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                //发件人邮件用户名、授权码
                return new PasswordAuthentication("525266345@qq.com", "Authorization code");
            }
        });
        //--开启debug模式,这样就可以查看到程序发送email的运行状态
        session.setDebug(true);
        
        //2. 通过session得到transport对象
        Transport ts = session.getTransport();
        //3. 使用邮箱的用户名和授权码连上邮件服务器
        ts.connect("smtp.qq.com", "525266345@qq.com", "Authorization code");
        //4. 创建邮件
        MimeMessage message = new MimeMessage(session);
            //--邮件的发件人
        message.setFrom(new InternetAddress("525266345@qq.com"));
            //--邮件的收件人
        message.setRecipient(Message.RecipientType.TO, new InternetAddress("525266345@qq.com"));
            //--邮件的标题
        message.setSubject("Hello...");
            //--邮件的文本内容
            //message.setContent("<h1 style='color: red'>你好...</h1>", "text/html;charset=UTF-8");

        //==================================================
        //准备 图片 数据
        MimeBodyPart image = new MimeBodyPart();
            //图片需要经过数据处理...  DataHandler
        DataHandler dh = new DataHandler(new FileDataSource("C:\\Users\\Administrator\\IdeaProjects\\JavaWeb\\功能扩展\\mail-java\\src\\1.png"));
        image.setDataHandler(dh);//在我们的Body中放入这个处理的图片数据
            //给图片设置一个id
        image.setContentID("bz.jpg");
    
        //准备 文本 数据
        MimeBodyPart text = new MimeBodyPart();//ContentID=cid
        text.setContent("这是一封邮件带图片<img src='cid:bz.jpg'/>的邮件","text/html;charset=UTF-8");
        
        //描述数据关系:整合
        MimeMultipart mm = new MimeMultipart();
        mm.addBodyPart(text);
        mm.addBodyPart(image);
        mm.setSubType("related");//最高是mixed
    
        //设置到消息中,保存修改
        message.setContent(mm);//把最后编辑好的邮件放到消息中
        message.saveChanges();//保存修改
        //==================================================
        
        //5. 发送邮件
        ts.sendMessage(message, message.getAllRecipients());
        //6.关闭连接
        ts.close();
    }
    
}
  • 如果报错如下:
javax.mail.MessagingException: Could not connect to SMTP host: smtp.qq.com, port: 465
javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
  • 解决方案
    • 方案一:检查JDK版本,我的是1.8.0_301。在JDK安装目录下,例如:C:\Program Files\Java\jdk1.8.0_301\jre\lib\security,查找java.security文件,打开后将jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, \这条语句的SSLv3, TLSv1, TLSv1.1, 这三项删除,即可。(但一般不建议改动JDK的文件)
    • 方案二:将以下代码段注释掉或者删掉。原因可能是QQ邮箱已经不再需要设置SSL加密。
        //关于QQ邮箱,还需要设置SSL加密,加上以下以下代码即可
        MailSSLSocketFactory sf = new MailSSLSocketFactory();
        sf.setTrustAllHosts(true);
        properties.put("mail.smtp.ssl.enable", "true");
        properties.put("mail.smtp.ssl.socketFactory", sf);
  1. 在JavaWeb项目中启用多线程发送邮件
  • pom.xml
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>4.0.1</version>
		</dependency>
  • web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
	
	<servlet>
		<servlet-name>RegisterServlet</servlet-name>
		<servlet-class>com.zach.servlet.RegisterServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>RegisterServlet</servlet-name>
		<url-pattern>/registerServlet.do</url-pattern>
	</servlet-mapping>
	
</web-app>
  • index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>注册</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/registerServlet.do" method="post">
    用户名:<input type="text" name="username"/><br/>&emsp;码:<input type="password" name="password"/><br/>&emsp;箱:<input type="text" name="email"/><br/>
    <input type="submit" value="注册"/>
</form>
</body>
</html>
  • info.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<h1>xxx网站温馨提示:</h1>
${message}

</body>
</html>
  • User.java
package com.zach.pojo;

import java.io.Serializable;

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 + '\'' +
                '}';
    }
}
  • RegisterServlet
package com.zach.servlet;

import com.zach.pojo.User;
import com.zach.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;

//脚手架:往里添加功能就行
public class RegisterServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    }
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //接收用户请求,封装成对象
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String email = req.getParameter("email");
    
        User user = new User(username,password,email);
        
        //用户注册成功之后,给用户发送一封邮件!
        //我们使用线程来专门发送邮件,防止出现耗时,和网站注册人数过多的情况,影响用户体验。
        Sendmail send = new Sendmail(user);
        //启动线程,线程启动之后就会执行run方法来发送邮件
        send.start();//如果用send.run();则并不是开启多线程,会加载完才跳转,有点慢。
    
        //注册用户
        req.setAttribute("message",
                "您已注册成功,我们已经发送了一封带有注册信息的电子邮件,请注意查收!如果网络不稳定,请等待片刻再查收。");
        req.getRequestDispatcher("info.jsp").forward(req,resp);
    }
}
  • Sendmail
package com.zach.utils;

import com.sun.mail.util.MailSSLSocketFactory;
import com.zach.pojo.User;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Properties;

//网站3秒原则:用户体验
    //多线程实现用户体验! (异步处理)
public class Sendmail extends Thread{
    //用于给用户发送邮件的邮箱
    private String from = "525266345@qq.com";
    //邮箱的用户名
    private String userName = "525266345@qq.com";
    //邮箱的密码
    private String password = "Authorization code";
    //发送邮件的服务器地址
    private String host = "smtp.qq.com";
    
    //“Service层调用Dao层,Servlet层调用Service层”时,使用的方式。
    private User user;
    public Sendmail(User user) {
        this.user = user;
    }
    
    @Override
    public void run() {
        try {
            Properties properties = new Properties();
            properties.setProperty("mail.host", host);//设置QQ邮件服务器
            properties.setProperty("mail.transport.protocol", "smtp");//邮件发送协议
            properties.setProperty("mail.smtp.auth", "true");//需要验证用户名密码
            
            //关于QQ邮箱,还需要设置SSL加密,加上以下以下代码即可
            //MailSSLSocketFactory sf = new MailSSLSocketFactory();
            //sf.setTrustAllHosts(true);
            //properties.put("mail.smtp.ssl.enable", "true");
            //properties.put("mail.smtp.ssl.socketFactory", sf);
            
            //使用javaMail发送邮件的5个步骤:
            //1. 创建定义整个应用程序所需的环境信息的Session对象
            Session session = Session.getDefaultInstance(properties, new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    //发件人邮件用户名、授权码
                    return new PasswordAuthentication(from, password);
                }
            });
                //--开启debug模式,这样就可以查看到程序发送email的运行状态
            session.setDebug(true);
            //2. 通过session得到transport对象
            Transport ts = session.getTransport();
            //3. 使用邮箱的用户名和授权码连上邮件服务器
            ts.connect(host, from, password);
            //4. 创建邮件
            MimeMessage message = new MimeMessage(session);
            message.setFrom(new InternetAddress(from));//发件人
            message.setRecipient(Message.RecipientType.TO, new InternetAddress(user.getEmail()));//收件人
            message.setSubject("用户注册邮件");//标题
                //--邮件的文本内容
            String info = "<h1 style='color: red'>恭喜您注册成功,您的用户名:</h1>"+user.getUsername()
                    +",您的密码:"+user.getPassword()+",请妥善保管,如有问题请联系网站客服。";
            message.setContent(info, "text/html;charset=UTF-8");
            message.saveChanges();
            
            //5. 发送邮件
            ts.sendMessage(message, message.getAllRecipients());
            //6. 关闭连接
            ts.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        
    }
}
  1. 在SpringBoot中实现(拓展)
  • pom.xml
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-mail</artifactId>
			<scope>test</scope>
		</dependency>
  • 自动生成的DemoApplication
package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {
    
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
    
}
  • 在application.properties中配置
spring.mail.username=525266345@qq.com
spring.mail.password=Authorization code
spring.mail.host=smtp.qq.com
spring.mail.properties.mail.smtp.ssl.enable=true
  • 在test文件夹下测试DemoApplicationTests
package com.example.demo;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;

import javax.mail.internet.MimeMessage;
import java.io.File;

@SpringBootTest
class DemoApplicationTests {
    
    @Autowired
    JavaMailSenderImpl mailSender;
    //这里mailSender有红色下划线:可能要在application.properties中进行对应配置。
    
    @Test
    void contextLoads() {
        //发送邮件
        //收件人
        //内容
    
        SimpleMailMessage message = new SimpleMailMessage();
        message.setSubject("西开Java");
        message.setText("Hello...");
        
        message.setFrom("525266345@qq.com");
        message.setTo("525266345@qq.com");
        
        mailSender.send(message);
    }
    
    @Test
    public void test2() throws Exception {
        MimeMessage mimeMessage = mailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
        
        helper.setSubject("西开Java");
        helper.setText("<h1>Hello...<h1>",true);
        
        //附件
        helper.addAttachment("img/1.png",new File("src/main/resources/img/1.png"));
        helper.addAttachment("img/2.png",new File("src/main/resources/img/2.png"));
        helper.addAttachment("img/3.png",new File("src/main/resources/img/3.png"));
        
        helper.setFrom("525266345@qq.com");
        helper.setTo("525266345@qq.com");
        
        mailSender.send(mimeMessage);
    }
    
}
  • 以上皆测试成功。
  • JavaWeb到此结束。

 
 

—————— THE END ——————
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zachsj

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值