JavaWeb之文件上传、下载以及邮件的发送

版权声明:转载请联系作者本人!!! https://blog.csdn.net/weixin_42061805/article/details/82695671

上传文件的要求

表单的要求

1.表单的提交方式必须为POST方式
2.必须添加表单的另一属性enctype=”multipart/form-data”

Servlet的要求

1.若表单中加属性enctype,则在Servlet无法使用req.getParameter(“xxx”)方法,任何表单项都会返回null。
2.在Servlet提供了另外一种获取表单数据的方法req.getInputStream(),得到的是整个请求体。

需要的jar包

commons-fileupload-1.2.2.jar
commons-io-2.6.jar

commons-fileupload介绍

从表单中获取请求体数据后,我们需要借助该包对请求体解析,解析完成后的数据存放在 FileItem对象当中,只需要用该对象的具体方法即可以得到我们想要的表单数据。
如何获得FileItem对象?
1.创建工厂:DiskFileItemFactory dff = new DiskFileItemFactory();
2.创建解析器:ServletFileUpload sfu = new ServletFileUpload(dff);
3.得到FileItem类型的LIst: List<FileItem> list = sfu.parseRequest(request)
4.遍历List,获得需要的数据。

FileItem介绍(不完全介绍)

方法 作用
getFieldName() 返回当前表单项的名称
getName() 返回上传文件的名称
getString(String charset) 获得当前表单项的值
isFormField() 是否是普通表单项
getSize() 返回上传文件的大小(字节数)
getInputStream() 返回上传文件对应的输入流
write(File file) 把上传的文件保存到指定文件中

示例:

<body>
  <h1>上传文件</h1>
  <form action='<c:url value='/UpLoadServlet'></c:url>' method="post" enctype="multipart/form-data">
    用户名:<input type="text" name="username"><br>
    照片:<input type="file" name="photo"><br>
    <input type="submit" value="上传">
  </form>
  </body>
package tqb.upload.web.servlet;

import java.io.File;
import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
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.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

@WebServlet("/UpLoadServlet")
public class UpLoadServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //处理post请求编码
        request.setCharacterEncoding("utf-8");

        // 创建工厂
        DiskFileItemFactory factory = new DiskFileItemFactory();

        // 创建解析器
        ServletFileUpload sfu = new ServletFileUpload(factory);

        // 获得Fileitem类型的List
        try {
            List<FileItem> list = sfu.parseRequest(request);

            FileItem f1 = list.get(0);
            FileItem f2 = list.get(1);

            System.out.println("普通表单项:" + f1.getFieldName() + "=" + f1.getString("utf-8"));
            System.out.println("文件表单项:");
            System.out.println("Content-Type:" + f2.getContentType());
            System.out.println(f2.getName());
            System.out.println(f2.getSize());

            try {
                f2.write(new File("C:\\Users\\lenovo\\Desktop\\photo.jpg"));
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        } catch (FileUploadException e) {
            throw new RuntimeException(e);
        }

    }

}

上传文件的细节

1.文件必须保存到WEB-INF中,避免用户可以从浏览器可以直接访问
2.文件名称相关问题
a.有的浏览器上传文件的文件名是绝对路径,需要切割!如:C:\hello\hello.txt
b.文件乱码或普通表单项乱码,解决办法: req.setCharacterEncoding(“utf-8”);
c.文件同名问题:解决办法: uuid
3.目录打散,不要在一个目录下放过多的文件
4.上传文件的大小限制
a.单个文件的大小限制
b.整个请求数据的大小限制

5.缓存大小与临时目录
代码实现:

package tqb.upload.web.servlet;

import java.io.File;
import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
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.FileUploadBase.FileSizeLimitExceededException;
import org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import cn.itcast.commons.CommonUtils;

@WebServlet("/UpLoadServlet")
public class UpLoadServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.getWriter().append("Served at: ").append(request.getContextPath());
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //编码设置
        response.setContentType("text/html;charset=utf-8");
        request.setCharacterEncoding("utf-8");

        //创建工厂
//      DiskFileItemFactory factory = new DiskFileItemFactory();
        //缓存大小与临时目录,第一个参数为上传文件大小超过多少时会在硬盘建立缓存目录(默认为10kb),第二个参数为缓存目录的位置
        DiskFileItemFactory factory = new DiskFileItemFactory(20 * 1024, new File("D:/temp"));
        //创建解析器
        ServletFileUpload sfu = new ServletFileUpload(factory);

        //限制单个文件的上传大小(1M)
//      sfu.setFileSizeMax(1024 * 1024);
        //限制整体请求体的大小(2M)
//      sfu.setSizeMax(2048 * 1024);
        //得到List
        try {

            List<FileItem> list = sfu.parseRequest(request);
            FileItem f1 = list.get(0);
            FileItem f2 = list.get(1);
            //得到普通表单项名称
//          f1.getFieldName();
            //得到普通表单项值
//          f1.getString();

            //得到文件根目录
            String root = this.getServletContext().getRealPath("/WEB-INF/files");

            //得到文件表单项名称
            String upName = f2.getName();

            //处理文件上传是带路径名
            int index = upName.lastIndexOf("\\");
            if (index != -1){
                upName = upName.substring(index + 1);
            }

            //处理文件同名问题,保存就按这个保存
            String newName = CommonUtils.uuid() + "_" + upName;

            //哈希方法打散目录
            /*
             * 1.获取哈希值,转16进制
             * 2.分别得到前两个字符
             * 3.创建目录
             * 4.将上传得文件保存到目录之中
             */
            int hashCode = newName.hashCode();
            String hexString = Integer.toHexString(hashCode);
            File path = new File(root,hexString.charAt(0) + "/" + hexString.charAt(1)); 
            //有该文件得话不创建,没有的话自动创建
            path.mkdirs();

            //将文件保存在指定位置
            try {
                f2.write(new File(path,newName));
            } catch (Exception e) {
                e.printStackTrace();
            }
        } catch (FileUploadException e) {
            if (e instanceof FileSizeLimitExceededException){
                request.setAttribute("msg", "文件大小超过1M,上传失败!");
                request.getRequestDispatcher("/index.jsp").forward(request, response);
            }
            if(e instanceof SizeLimitExceededException){
                request.setAttribute("msg", "整体大小超过2M,上传失败!");
                request.getRequestDispatcher("/index.jsp").forward(request, response);
            }
        }
    }
}

邮件的发送

有关于邮件的协议
SMTP 简单邮件传输协议 发邮件的协议 端口号:25 服务器名称为:stmp.xxx.xxx 如:stmp.163.com
POP3 邮局协议第三版 收邮件的协议 端口号:110 服务器名称:pop3.xxx.xxx 如:pop3.163.com
IMAP 因特网消息访问协议 收发邮件的协议(了解)
依赖的jar包:
javax.mail-1.6.2.jar
activation-1.1.1.jar

不带附件的邮件

package tqb.mail;

import java.util.Properties;

import javax.mail.Authenticator;
import javax.mail.Message.RecipientType;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import org.junit.Test;

/**
 * 邮件的发送(不带附件)
 * @author tqb
 *
 */
public class MyMail {
    /*
     * 
     */
    @Test
    public void fun() throws AddressException, MessagingException{
        /*
         * 1.获得Session
         */
        Properties props = new Properties();
        props.setProperty("mail.host", "smtp.163.com");
        props.setProperty("mail.smtp.auth", "true");

        Authenticator auth = new Authenticator() {
            @Override
            public PasswordAuthentication getPasswordAuthentication() {
                /*
                 * 用户名,密码
                 */
                return new PasswordAuthentication("username", "password");
            }
        };

        Session session = Session.getInstance(props, auth);

        /*
         * 2.获得MimeMessage
         */
        MimeMessage msg = new MimeMessage(session); 
        //发件人
        msg.setFrom(new InternetAddress("[email protected]"));
        //收件人
        msg.setRecipients(RecipientType.TO, "[email protected]");
        //抄送人
//      msg.setRecipients(RecipientType.CC, "");
        //暗送人(看不到,但是会收到消息)
//      msg.setRecipients(RecipientType.BCC, "");
        //标题
        msg.setSubject("这是一个测试邮件");
        //正文
        msg.setContent("邮件正文,测试邮件,不要理会!!!", "text/html;charset=utf-8");

        /*
         * 3.发送邮件
         */
        Transport.send(msg);
    }
}

带附件的邮件

package tqb.mail;

import java.io.File;
import java.io.IOException;
import java.util.Properties;

import javax.mail.Authenticator;
import javax.mail.Message.RecipientType;
import javax.mail.MessagingException;
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 javax.mail.internet.MimeUtility;

import org.junit.Test;

/**
 * 发送带有附件的邮件
 * @author tqb
 *
 */
public class MyMail2 {
    @Test
    public void fun() throws MessagingException, IOException{
        /*
         * 创建Session
         */
        Properties props = new Properties();
        props.setProperty("mail.host", "smtp.163.com");
        props.setProperty("mail.smtp.auth", "true");

        Authenticator auth = new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("username","password");
            }
        };

        Session session = Session.getInstance(props, auth);

        /*
         * 得到mimeMessage
         */
        MimeMessage msg = new MimeMessage(session);

        msg.setSubject("带附件的邮件");

        //创建多部分主体
        MimeMultipart list = new MimeMultipart();
        //创建MimeBodyPart
        MimeBodyPart part1 = new MimeBodyPart();
        part1.setContent("这是带有附件的垃圾邮件","text/html;charset=utf-8");
        MimeBodyPart part2 = new MimeBodyPart();
        //附件
        part2.attachFile(new File("C:\\Users\\lenovo\\Desktop\\dogcom.exe"));
        //附件的名称+编码(防止乱码)
        part2.setFileName(MimeUtility.encodeWord("狗子.exe"));

        //将MimeBodyPart添加至MimeMultipart
        list.addBodyPart(part1);
        list.addBodyPart(part2);
        msg.setContent(list);
        msg.setFrom(new InternetAddress("[email protected]"));
        msg.setRecipients(RecipientType.TO, "[email protected]");

        /*
         * 发送邮件
         */
        Transport.send(msg);
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_42061805/article/details/82695671
今日推荐