本週總結(文件上傳,下載,郵件)

文件上傳

1.上傳對錶單限制

  • method="post"
  • enctype="multipart/form-data"
  • 表單中須要添加文件表單項:<input type="file" name="xxx" />
<h3>${msg }</h3>
 <form action="xxx" method="post" enctype="multipart/form-data">
      用戶名;<input type="text" name="username"/><br/>
      照 片:<input type="file" name="zhaoPian"/><br/>
      <input type="submit" value="上傳"/>
    </form>

2.上傳對Servlet限制

  • 文件上傳不能使用BaseServlet
  • request.getParametere("xxx");這個方法在表單爲enctype="multipart/form-data"時,它做廢了。它永遠都返回null
  • ServletInputStream request.getInputStream();包含整個請求的體!

3.上傳三步

導入jar(commons-fileupload)html

  • commons-fileupload.jar
  • commons-io.jar

相關類:java

  • 工廠:DiskFileItemFactory
  • 解析器:ServletFileUpload
  • 表單項:FileItem數組

    1.建立工廠:DiskFileItemFactory factory = new DiskFileItemFactory();
     2.建立解析器:ServletFileUpload sfu = new ServletFileUpload(factory);
     3.使用解析器來解析request,獲得FileItem集合:List<FileItem> fileItemList = sfu.parseRequest(request);

4.FileItem

  1. boolean isFormField():是否爲普通表單項!返回true爲普通表單項,若是爲false即文件表單項!
  2. String getFieldName():返回當前表單項的名稱;
  3. String getString(String charset):返回表單項的值;
  4. String getName():返回上傳的文件名稱
  5. long getSize():返回上傳文件的字節數
  6. InputStream getInputStream():返回上傳文件對應的輸入流
  7. void write(File destFile):把上傳的文件內容保存到指定的文件中。
  8. String getContentType();獲取上傳的文件的類型

5.上傳的細節

  1. 保存到WEB-INF下!(目的是不讓瀏覽器直接訪問到)
  2. 有的瀏覽器上傳的文件名是絕對路徑,這須要切割
  3. 目錄打散瀏覽器

    哈希打散:  
         經過文件名稱獲得int值,即調用hashCode()
         它int值轉換成16進制0~9, A~F
         獲取16進制的前兩位用來生成目錄,目錄爲二層!例如:1B2C3D4E5F,/1/B/保存文件。

6.代碼

public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        
        /*
         * 上傳三步
         */
        // 工廠,設置緩存,超過20k,向目錄保存
        DiskFileItemFactory factory = new DiskFileItemFactory(20*1024, new File("F:/f/temp"));
        // 解析器
        ServletFileUpload sfu = new ServletFileUpload(factory);
        //sfu.setFileSizeMax(100 * 1024);//限制單個文件大小爲100K
        //sfu.setSizeMax(1024 * 1024);//限制整個表單大小爲1M
        
        // 解析,獲得List
        try {
            List<FileItem> list = sfu.parseRequest(request);
            FileItem fi = list.get(1);
            
            /*
             * 1. 獲得文件保存的路徑
             */
            String root = this.getServletContext().getRealPath("/WEB-INF/files/");
            /*
             * 2. 生成二層目錄
             *   1). 獲得文件名稱
             *   2). 獲得hashCode
             *   3). 轉發成16進制
             *   4). 獲取前二個字符用來生成目錄
             */
            String filename = fi.getName();//獲取上傳的文件名稱
            /*
             * 處理文件名的絕對路徑問題
             */
            int index = filename.lastIndexOf("\\");
            if(index != -1) {
                filename = filename.substring(index+1);
            }
            /*
             * 給文件名稱添加uuid前綴,處理文件同名問題
             */
            String savename = CommonUtils.uuid() + "_" + filename;
            
            /*
             * 1. 獲得hashCode
             */
            int hCode = filename.hashCode();
            String hex = Integer.toHexString(hCode);
            
            /*
             * 2. 獲取hex的前兩個字母,與root鏈接在一塊兒,生成一個完整的路徑
             */
            File dirFile = new File(root, hex.charAt(0) + "/" + hex.charAt(1));
            
            /*
             * 3. 建立目錄鏈
             */
            dirFile.mkdirs();
            
            /*
             * 4. 建立目錄文件
             */
            File destFile = new File(dirFile, savename);
            
            /*
             * 5. 保存
             */
            fi.write(destFile);
            
            
        } catch (FileUploadException e) {
            if(e instanceof FileUploadBase.FileSizeLimitExceededException) {
                request.setAttribute("msg", "您上傳的文件超出了100KB!");
                request.getRequestDispatcher("/form.jsp").forward(request, response);
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

文件下載

1.下載就是向客戶端響應字節數據!

把一個文件變成字節數組,使用response.getOutputStream()來各應給瀏覽器!!!

2.下載的要求

兩個頭一個流!緩存

  • Content-Type:你傳遞給客戶端的文件是什麼MIME類型,例如:image/pjpegsession

    經過文件名稱調用ServletContext的getMimeType()方法,獲得MIME類型!
  • Content-Disposition:它的默認值爲inline,表示在瀏覽器窗口中打開!attachment;filename=xxxjsp

    在filename=後面跟隨的是顯示在下載框中的文件名稱!
  • 流:要下載的文件數據!ide

    本身new一個輸入流便可!

3.代碼

@Override
    public void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        /*
         * 兩個頭一個流
         * 1. Content-Type
         * 2. Content-Disposition
         * 3. 流:下載文件的數據
         */
        String filename = "F:/清白之年.mp3";
        
        // 爲了使下載框中顯示中文文件名稱不出亂碼!
        String framename = filenameEncoding("清白之年.mp3", req);
        
        String contentType = this.getServletContext()
                .getMimeType(filename);//經過文件名稱獲取MIME類型
        String contentDisposition = "attachment;filename=" + framename;
        // 一個流
        FileInputStream input = new FileInputStream(filename);
        
        //設置頭
        resp.setHeader("Content-Type", contentType);
        resp.setHeader("Content-Disposition", contentDisposition);
        
        // 獲取綁定了響應端的流
        ServletOutputStream output = resp.getOutputStream();
        
        IOUtils.copy(input, output);//把輸入流中的數據寫入到輸出流中。
        
        input.close();
    }
    
    // 用來對下載的文件名稱進行編碼的!(通用方案)
    public static String filenameEncoding(String filename, HttpServletRequest request) throws IOException {
        String agent = request.getHeader("User-Agent"); //獲取瀏覽器
        if (agent.contains("Firefox")) {
            BASE64Encoder base64Encoder = new BASE64Encoder();
            filename = "=?utf-8?B?"
                    + base64Encoder.encode(filename.getBytes("utf-8"))
                    + "?=";
        } else if(agent.contains("MSIE")) {
            filename = URLEncoder.encode(filename, "utf-8");
        } else {
            filename = URLEncoder.encode(filename, "utf-8");
        }
        return filename;
    }

JavaMail

注意:通常郵箱須要開通POP3/SMTP/IMAP功能,發過去郵件極可能在垃圾箱裏面post

1.導入jar測試

mail.jar
activation.jar

2.主要類

javax.mail.Session
javax.mail.internet.MimeMessage
javax.mail.Transport

3.代碼

  • 無附件
@Test
    public void fun1() throws Exception {
        /*
         * 1. 獲得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("itcast_cxf", "itcast");//帳號密碼
            }
        };
        
        Session session = Session.getInstance(props, auth);
        
        /*
         * 2. 建立MimeMessage
         */
        MimeMessage msg = new MimeMessage(session);
        msg.setFrom(new InternetAddress("itcast_cxf@163.com"));//設置發件人
        msg.setRecipients(RecipientType.TO, "itcast_cxf@126.com");//設置收件人
        //msg.setRecipients(RecipientType.CC, "itcast_cxf@sohu.com");//設置抄送
        //msg.setRecipients(RecipientType.BCC, "itcast_cxf@sina.com");//設置暗送
        
        msg.setSubject("這是來自ITCAST的測試郵件");
        msg.setContent("這就是一封垃圾郵件!", "text/html;charset=utf-8");
        
        /*
         * 3. 發
         */
        Transport.send(msg);
    }
  • 有附件
@Test
    public void fun2() throws Exception {
        /*
         * 1. 獲得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("itcast_cxf", "itcast");
            }
        };
        
        Session session = Session.getInstance(props, auth);
        
        /*
         * 2. 建立MimeMessage
         */
        MimeMessage msg = new MimeMessage(session);
        msg.setFrom(new InternetAddress("itcast_cxf@163.com"));//設置發件人
        msg.setRecipients(RecipientType.TO, "itcast_cxf@126.com");//設置收件人
        
        msg.setSubject("這是來自ITCAST的測試郵件有附件");
        
        /*
         * 當發送包含附件的郵件時,郵件體就爲多部件形式!
         * 1. 建立一個多部件的部件內容!MimeMultipart
         *   MimeMultipart就是一個集合,用來裝載多個主體部件!
         * 2. 咱們須要建立兩個主體部件,一個是文本內容的,另外一個是附件的。
         *   主體部件叫MimeBodyPart
         * 3. 把MimeMultipart設置給MimeMessage的內容!
         */
        MimeMultipart list = new MimeMultipart();//建立多部份內容
        
        // 建立MimeBodyPart
        MimeBodyPart part1 = new MimeBodyPart();
        // 設置主體部件的內容
        part1.setContent("這是一封包含附件的垃圾郵件", "text/html;charset=utf-8");
        // 把主體部件添加到集合中
        list.addBodyPart(part1);
        
        
        // 建立MimeBodyPart
        MimeBodyPart part2 = new MimeBodyPart();
        part2.attachFile(new File("F:/f/白冰.jpg"));//設置附件的內容
        part2.setFileName(MimeUtility.encodeText("大美女.jpg"));//設置顯示的文件名稱,其中encodeText用來處理中文亂碼問題
        list.addBodyPart(part2);
        
        msg.setContent(list);//把它設置給郵件做爲郵件的內容。
        
        /*
         * 3. 發
         */
        Transport.send(msg);        
    }
相關文章
相關標籤/搜索