JavaWeb入门到入土_Day06

16. 文件传输原理及介绍

17. 文件上传原理

导包
commons-fileupload-1.4.jar
commons-io-2.11.0.jar

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
  <title>$Title$</title>
</head>
<body>
<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.wang.servlet.FileServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>FileServlet</servlet-name>
        <url-pattern>/upload.do</url-pattern>
    </servlet-mapping>
</web-app>

FileServlet.java

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;

public class FileServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 判断上传的表单是普通form表单还是文件form表单
        if (!ServletFileUpload.isMultipartContent(request)) {
            // 终止方法运行,说明这是一个普通的表单,直接返回
            return;
        }
        // 创建上传文件的保存路径,建议在WEB-INF路径下,安全,用户无法直接访问上传的文件
        String uploadPath = this.getServletContext().getRealPath("/WEB-INF/upload");
        File uploadFile = new File(uploadPath);
        if (!uploadFile.exists()) {   // 若路径不存在就创建路径
            uploadFile.mkdir();
        }

        // 临时路径存放临时文件,假如文件超过了预期的大小,就将其放到一个临时文件中,过几天自动删除,或者提醒用户转存为永久
        String tempPath = this.getServletContext().getRealPath("/WEB-INF/temp");
        File tempFile = new File(tempPath);
        if (!tempFile.exists()) {   // 若路径不存在就创建路径
            tempFile.mkdir();
        }
        
        // 处理上传的文件,一般都需要通过流来获取,我们可以使用request.getInputStream()获取原生态的文件上传流,十分麻烦
        // 建议使用Apache的文件上传组件来实现,common-fileupload,它需要依赖于commons-io组件

        // 1.创建DiskFileItemFactory对象,处理文件路径上传或者大小限制
        DiskFileItemFactory factory = createDiskFileItemFactory(tempFile);
        // 2.获取ServletFileUpload
        ServletFileUpload upload = creatServletFileUpload(factory);
        // 3.处理上传的文件
        String msg = uploadFile(request, uploadPath, upload);

        // 转发
        request.setAttribute("msg", msg);
        request.getRequestDispatcher("/info.jsp").forward(request, response);
    }

    private String uploadFile(HttpServletRequest request, String uploadPath, ServletFileUpload upload) throws IOException {
        String msg = "";
        // 把前端请求解析,封装成一个FileItem对象,需要从ServletFileUpload对象中获取
        try {
            List<FileItem> fileItems = upload.parseRequest(request);
            for (FileItem fileItem : fileItems) {
                if (fileItem.isFormField()) {   // 判断是否为普通表单:是true否false
                    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);
        // 设置总共能够上传文件的大小 1024 = 1kb * 1024 = 1M * 10 = 10M
        upload.setSizeMax(1024 * 1024 * 10);
        return upload;
    }

    private DiskFileItemFactory createDiskFileItemFactory(File tempFile) {
        DiskFileItemFactory factory = new DiskFileItemFactory();
        //通过这个工厂设置一个缓冲区,当上传的文件大于这个缓冲区的时候,将其放到临时文件中
        factory.setSizeThreshold(1024 * 1024);   // 缓冲区大小为1M
        factory.setRepository(tempFile);   // 临时目录的保存目录
        return factory;
    }
}

18. 邮件传输原理及实现

导包
activation-1.1.1.jar
mail-1.4.7.jar

MailDemo01.java

import com.sun.mail.util.MailSSLSocketFactory;

import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Properties;

public class MailDemo01 {
    public static void main(String[] args) throws Exception {
        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("2577231582@qq.com", "授权码");
            }
        });
        // --开启debug模式,这样就可以查看到程序发送email的运行状态
        session.setDebug(true);
        // 2.通过session得到transport对象
        Transport ts = session.getTransport();
        // 3.使用邮箱的用户名和授权码连上邮件服务器
        ts.connect("smtp.qq.com", "2577231582@qq.com", "授权码");
        // 4.创建邮件
        MimeMessage message = new MimeMessage(session);
        // --邮件的发件人
        message.setFrom(new InternetAddress("2577231582@qq.com"));
        // --邮件的收件人
        message.setRecipient(Message.RecipientType.TO, new InternetAddress("2577231582@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();
    }
}

MailDemo02.java

import com.sun.mail.util.MailSSLSocketFactory;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
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 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("2577231582@qq.com", "授权码");
            }
        });
        // --开启debug模式,这样就可以查看到程序发送email的运行状态
        session.setDebug(true);
        // 2.通过session得到transport对象
        Transport ts = session.getTransport();
        // 3.使用邮箱的用户名和授权码连上邮件服务器
        ts.connect("smtp.qq.com", "2577231582@qq.com", "授权码");
        // 4.创建邮件
        MimeMessage message = new MimeMessage(session);
        // --邮件的发件人
        message.setFrom(new InternetAddress("2577231582@qq.com"));
        // --邮件的收件人
        message.setRecipient(Message.RecipientType.TO, new InternetAddress("2577231582@qq.com"));
        // --邮件的标题
        message.setSubject("hello");
        
        // ======================准备邮件数据======================= 
        // 图片数据
        MimeBodyPart image = new MimeBodyPart();
        // 图片需要数据处理  DataHandler
        DataHandler dh = new DataHandler(new FileDataSource("src/resources/bz.jpg"));   
        image.setDataHandler(dh);   // 在Body中放入处理的图片数据
        image.setContentID("bz.jpg");   // 给图片设置一个id 

        // 文本数据
        MimeBodyPart text = new MimeBodyPart();
        text.setContent("这是一封邮件带图片<img src='cid:bz.jpg'/>的邮件", "text/html;charset=UTF-8");
        
        // 描述数据关系
        MimeMultipart mm = new MimeMultipart();
        mm.addBodyPart(text);
        mm.addBodyPart(image);
        /** 
        * 仅文本为alternative;
        * 文本+图片为related;
        * 文本+图片+文件为mixed
        */      
        mm.setSubType("related");
        // 放到消息中,保存修改
        message.setContent(mm);   // 最后编辑好的邮件放到消息当中
        message.saveChanges();   // 保存修改
        // ========================================================
        
        // 5.发送邮件
        ts.sendMessage(message, message.getAllRecipients());
        // 6.关闭连接
        ts.close();
    }
}

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

pom.xml

    <dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
        </dependency>
        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>1.4.7</version>
        </dependency>
        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>1.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.10</version>
        </dependency>
    </dependencies>

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/>
    密码:<input type="password" name="password"/><br/>
    邮箱:<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>
${message}
</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-mapping>
        <servlet-name>registerServlet</servlet-name>
        <url-pattern>/registerServlet.do</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>registerServlet</servlet-name>
        <servlet-class>com.wang.servlet.RegisterServlet</servlet-class>
    </servlet>
</web-app>

User.java

import java.io.Serializable;
import lombok.*;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {
    private String userName;
    private String password;
    private String email;
}

RegisterServlet.java

import com.wang.pojo.User;
import com.wang.util.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 doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 接受用户请求,封装成对象
        String userName = request.getParameter("userName");
        String password = request.getParameter("password");
        String email = request.getParameter("email");

        User user = new User(userName, password, email);
        SendMail sendMail = new SendMail(user);
        // start方法启动线程,之后线程会执行run方法来发送邮件;
        // 直接执行run方法会导致用户在网站页面等候邮件发送完毕,响应速度不符合常理
        sendMail.start();

        request.setAttribute("message", "注册邮件发送成功");
        request.getRequestDispatcher("info.jsp").forward(request, response);
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}
}

SendMail.java

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

import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Properties;

public class SendMail extends Thread {

    private String from = "2577231582@qq.com";
    private String userName = "2577231582@qq.com";
    private String password = "授权码";
    private String host = "smtp.qq.com";
    private User user;

    public SendMail(User user) {
        this.user = user;
    }

    @Override
    public void run() {
        try {
            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(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(userName));
            // --邮件的收件人
            message.setRecipient(Message.RecipientType.TO, new InternetAddress(userName));
            // --邮件的标题
            message.setSubject("用户注册邮件");
            // --邮件的文本内容
            String info = "恭喜您注册成功,您的用户名:" + user.getUsername() + "您的密码:" + user.getPassword() + ", 请妥善保管,如有问题请联系网站客服!!!"
            message.setContent(info, "text/html;charset=UTF-8");
            message.saveChages();
            // 5.发送邮件
            ts.sendMessage(message, message.getAllRecipients());
            // 6.关闭连接
            ts.close();
        } catch (Exception e) {
            e.printStackTrace(e);
        }
    }
}

注意:spring框架可以用JavaMailSenderImpl实现

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值