文件传输和邮件发送

文件传输:

文件上传的注意事项:

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

        ②为了防止文件覆盖的现象发生,要为上传文件产生一个唯一的文件名(时间戳或者uuid)

        ③要限制上传文件的最大值

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

FileItem类

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

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

        <form action="${pageContext.request.contextPath}/upload.do" enctype="multipart/form-data" method="post">
            上传用户:<input type="text" name="username"><br>
            上传文件1:<input type="file" name="file1"><br>
            上传文件2:<input type="file" name="file2"><br>
            <input type="submit">   |   <input type="reset">
        </form>

常用方法介绍:

//isFormField方法用于判断FileItem类对象封装的数据是一个普通文本表单,还是一个文件表单
//如果是普通表单字段则返回true,否则返回false
boolean isFormField();

//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列表的形式返回。使用该方法处理上传文件简单易用。


public class FileServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
        //判断上传的文件是普通表单还是带文件的表单
        if(!ServletFileUpload.isMultipartContent(req)){
            return; //终止方法运行,说明这是一个普通的表单,直接返回
        }
        try{
            //创建上传文件的保存路径,建议在安全的、用户无法直接访问的目录下,比如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 = new DiskFileItemFactory();
            //2.获取ServletFileUpload
            ServletFileUpload upload = new ServletFileUpload(factory);
            //3.处理上传的文件
            //把前端请求解析,封装成一个FileItem对象,需要从ServletFileUpload对象中获取
            List<FileItem> fileItems = upload.parseRequest(req);
            //fileItem是指每一个表单对象
            for(FileItem fileItem : fileItems){
                //判断上传的文件是普通的表单,还是带文件的表单
                if(fileItem.isFormField()){ //是普通表单
                    //getFileName是指前端表单,每一个输入项的name
                    String name = fileItem.getFieldName();
                    String value = fileItem.getString("UTF-8");
                    System.out.println(name + ":" + value);
                }else { //是文件
                    //========================处理文件===============================
                    String msg = "文件上传失败";
                    String uploadFileName = fileItem.getName();
                    //可能存在文件名不合法的情况
                    if(uploadFileName.trim().equals("") || uploadFileName == null){
                        continue;   //这个文件就不用管了,直接去判断下一个文件
                    }
                    //获得上传的文件名  /images/girl/hajie.png
                    String fileName = uploadFileName.substring(uploadFileName.lastIndexOf("/")+1);
                    //获得文件后缀名
                    String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".")+1);
                    //如果文件后缀名fileExtName不是我们需要的,就直接return,不处理,告诉用户文件类型不对
                    //可以使用UUID(唯一识别的通用码),保证文件名唯一;UUID.randomUUID().随机生成一个唯一识别的通用码
                    String uuidPath = UUID.randomUUID().toString();
                    //========================存放地址===============================
                    //存到哪?uploadPath
                    //我呢间真实存在的路径 realPath
                    String realPath = uploadPath + "/" + uuidPath;
                    //给每个文件创建一个对应的文件夹
                    File realPathFile = new File(realPath);
                    if(!realPathFile.exists()){
                        realPathFile.mkdir();
                    }
                    //========================文件传输===============================
                    //获得文件上传的流
                    InputStream inputStream = fileItem.getInputStream();
                    //创建一个文件输出流
                    //realPath = 真实的文件夹
                    //差了一个文件,加上输出文件的名字 + "/" + uuidFileName
                    FileOutputStream fileOutputStream = new FileOutputStream(realPath + "/" + fileName);
                    //创建一个缓冲区
                    byte[] buffer = new byte[1024*1024];
                    //判断是否读取完毕
                    int len = 0;
                    while ((len = inputStream.read(buffer)) > 0){
                        fileOutputStream.write(buffer,0,len);
                    }
                    //关闭流
                    fileOutputStream.close();
                    inputStream.close();
                    //上传成功,清除临时文件
                    fileItem.delete();
                    msg = "文件上传成功";
                    //servlet请求转发消息
                    req.setAttribute("msg",msg);
                    req.getRequestDispatcher("info.jsp").forward(req,resp);
                }
            }
        } catch (FileUploadException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ServletException e) {
            e.printStackTrace();
        }
    }
}

邮件发送:

        发送邮件:SMTP协议

        接收邮件:POP3协议

        SMTP服务器地址:一般是smtp.xxx.com,每一个网站都有自己的服务器地址(固定的)

        比如163邮箱是smtp.163.com,qq邮箱是smtp.qq.com

原理图:

1、导入依赖

    <dependencies>
        <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>
    </dependencies>

2、授权码 

要发送邮件,需要获得协议和支持(开启 SMTP 和 POP3 服务)

在设置里面开启POP3/SMTP服务,就可以获得授权码 

3、简单邮件:没有附件和邮件(纯文本邮件)

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

public class Test {
    //简单邮件:没有附件和图片,纯文本邮件 
    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对象
        //QQ才有,其他邮箱不用
        Session session = Session.getDefaultInstance(properties, new Authenticator() {
                            @Override
                            protected PasswordAuthentication getPasswordAuthentication() {
                                //发送人邮件用户名,授权码
                                return new PasswordAuthentication("123@qq.com","yctvnzqvixlbhjfa");
                            }
        });
        //2.通过Session得到transport对象
        Transport transport = session.getTransport();
        //3.使用邮箱的用户名和授权码连上邮件服务器
        transport.connect("smtp.qq.com","123@qq.com","yctvnzqvixlbhjfa");
        //4.创建邮件:写邮件
        //①注意需要传递Session
        MimeMessage message = new MimeMessage(session);
        //②指明邮件的发件人
        message.setFrom(new InternetAddress("123@qq.com"));
        //③指明邮件的收件人,现在发件人和收件人是一样的,那就是自己给自己发
        message.setRecipients(Message.RecipientType.TO, new InternetAddress[]{new InternetAddress("123@qq.com")});
        //④邮件的标题
        message.setSubject("邮件的主题(只包含文本的简单邮件)");
        //⑤邮件的文本内容
        message.setContent("<h1 style='color:red'>你好呀~</h1>","text/html;charset=utf-8");
        //5.发送邮件
        transport.sendMessage(message,message.getAllRecipients());
        //6.关闭连接
        transport.close();
    }
}

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

4、复杂邮件(正文带图片)


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 Test {
    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对象
        //QQ才有,其他邮箱不用
        Session session = Session.getDefaultInstance(properties, new Authenticator() {
                            @Override
                            protected PasswordAuthentication getPasswordAuthentication() {
                                //发送人邮件用户名,授权码
                                return new PasswordAuthentication("123@qq.com","yctvnzqvixlbhjfa");
                            }
        });
        //2.通过Session得到transport对象
        Transport transport = session.getTransport();
        //3.使用邮箱的用户名和授权码连上邮件服务器
        transport.connect("smtp.qq.com","123@qq.com","yctvnzqvixlbhjfa");
        //4.创建邮件:写邮件
        //①注意需要传递Session
        MimeMessage message = new MimeMessage(session);
        //②指明邮件的发件人
        message.setFrom(new InternetAddress("123@qq.com"));
        //③指明邮件的收件人,现在发件人和收件人是一样的,那就是自己给自己发
        message.setRecipients(Message.RecipientType.TO, new InternetAddress[]{new InternetAddress("123@qq.com")});
        //④邮件的标题
        message.setSubject("邮件的主题(复杂邮件)");
        //⑤文件内容
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        //准备图片数据
        MimeBodyPart img = new MimeBodyPart();
        //图片需要经过数据处理,需要传入图片路径
        DataHandler dataHandler = new DataHandler(new FileDataSource("D:\\My_______________Program\\Java\\my_java\\Email\\src\\main\\resources\\1.png"));
        img.setDataHandler(dataHandler);    //在我们的Body中,放入这个处理的图片数据
        img.setContentID("111");    //给图片设置一个ID
        //准备正文数据
        MimeBodyPart text = new MimeBodyPart();
        text.setContent("这是一封邮件正文带图片<img src='cid:111'>的邮件","text/html;charset=UTF-8");
        //描述数据关系
        MimeMultipart mimeMultipart = new MimeMultipart();
        mimeMultipart.addBodyPart(text);
        mimeMultipart.addBodyPart(img);
        mimeMultipart.setSubType("related");
        //设置到消息中,保存修改
        message.setContent(mimeMultipart);  //把最后编辑好的邮件,放到消息当中
        message.saveChanges();  //保存修改
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        //5.发送邮件
        transport.sendMessage(message,message.getAllRecipients());
        //6.关闭连接
        transport.close();
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值