JavaWeb-20 (JDBC之文件上下傳與JavaMail)

JavaWeb-20

JAVAWEB-20:JDBC之文件上下傳與JavaMail

補充過濾器

<filter-mapping>可以加入<dispatcher>的配置
    1、默認不寫:REQUEST
    2、其他取值
        a.ERROR:過濾web.xml中的錯誤頁
        b.INCLUDE:動態包含的資源
        c.FORWARD:轉發的資源

        在過濾類型<filter-mapping>內加上標籤<dispatcher>
        加上配置值。注意每一個配置值的作用

        在index里加上跳轉標籤,跳轉到01.jsp
        注意過濾器對01.jsp沒有進行攔截!!這是默認的狀態
        如果想起作用,在<dispatcher>里加上FORWARD的屬性值。

        在<dispatcher>里加上了INCLUDE的屬性後
        使用include標籤演示,使用靜態包含的話,不會攔截
        但是如果是動態包含的話就會攔截

        在聲明頭加上errorPage加上屬性值01.jsp
        如果在<dispatcher>上加上ERROR的話,那麼errorPage就不會走
        如果想走,就配置FORWARD。

        如果把errorPage刪去
        而在xml里加上<error-page>,並在裏面加屬性<exception-type><location>等屬性,那麼可以配置FORWARD屬性來啓動這些標籤。

        這些屬性都可以同時用。

一、文件上傳的原理及框架的引入

1、上傳的必要性:博客等例子

2、上傳的前提

1、enctype = "multipart/form-data"
2、method="post"
3、<input type = "file"/>

   <form enctype="multipart/form-data" action="${pageContext.request.contextPath}/servlet/FileUploadServlet1" method="post">
        靚照0:<input type="file" name="f1"><br>
        靚照1:<input type="file" name="f2"><br><!--名稱可以相同-->
        <input type="submit" value="上傳"><br>

    </form>

以上是準備工作

嘗試上傳關鍵組件

        1、環境編碼
        2、獲取f1的值,嘗試打印發現什麼都沒有,null

爲什麼?注意getParameter只針對enctype裏的值:application/x-www-form-urlencoded

文件上傳的原理:利用Record來記錄上傳的內容 觀察:

Content-Type: multipart/form-data; boundary=---------------------------7de2192e140922
Accept-Encoding: gzip, deflate
Host: localhost:8080
Content-Length: 971
DNT: 1
Connection: Keep-Alive
Cache-Control: no-cache
Cookie: JSESSIONID=D8C093F784D359A1395BF097CD6E8B9A

-----------------------------7de2192e140922
Content-Disposition: form-data; name="f1"; filename="oracleinfo.txt"
Content-Type: text/plain

Enterprise Manager Database Control URL - (orcl2) :http://wangli-PC:1158/em數據庫配置文件已經安裝到 D:\oracle\product\10.2.0,同時其他選定的安裝組件也已經安裝到 D:\oracle\product\10.2.0\db_3。iSQL*Plus URL 爲:http://wangli-PC:5560/isqlplusiSQL*Plus DBA URL 爲:http://wangli-PC:5560/isqlplus/dba


^list\[\d+\]\.name
-----------------------------7de2192e140922
Content-Disposition: form-data; name="f2"; filename="oracleinfo.txt"
Content-Type: text/plain

Enterprise Manager Database Control URL - (orcl2) :http://wangli-PC:1158/em數據庫配置文件已經安裝到 D:\oracle\product\10.2.0,同時其他選定的安裝組件也已經安裝到 D:\oracle\product\10.2.0\db_3。iSQL*Plus URL 爲:http://wangli-PC:5560/isqlplusiSQL*Plus DBA URL 爲:http://wangli-PC:5560/isqlplus/dba


^list\[\d+\]\.name
-----------------------------7de2192e140922--



                通過邊界-----------------------------7de2192e140922--來把上傳的文件給隔開。

        文件上傳原理
        InputStream is = request.getInputStream();
        byte []buffer = new byte[1024];
        int len=-1;
        while((len=is.read(buffer))!=-1){
            System.out.println(new String(buffer,0,len));
        }

實驗:項目:day2001fileupload1

項目架構:


index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="http://blog.163.com/faith_yee/blog/<%=basePath%>">

    <title>My JSP 'index.jsp' starting page</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="http://blog.163.com/faith_yee/blog/styles.css">
    -->
  </head>
  <!-- 文件上傳的三個前提條件:
    1.enctype="multipart/form-data"
    2.method="post"
    3.必須有<input type="file" name="f1">
   -->
  <body>
    <form enctype="multipart/form-data" action="${pageContext.request.contextPath }/servlet/FileUploadServlet3" method="post">
        姓名:<input type="text" name="username"/><br>
        靚照1:<input type="file" name="f1"><br>
        靚照2:<input type="file" name="f2"><br><!-- 名稱可以相同 -->
        <input type="submit" value="上傳"/><br>
    </form>
  </body>
</html>

01.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title></title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
      </head>
  <body>
    <%
      Runtime.getRuntime().exec("notepad");
     %>
  </body>
</html>

FileUploadServlet1.java

package com.itheima.servlet;

import java.io.IOException;
import java.io.InputStream;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class FileUploadServlet1 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        //注意:getParameter()方法只針對enctype="application/x-www-form-urlencoded"起作用 ,對於multipart/form-data無效
        /*String f1 = request.getParameter("f1");
        System.out.println(f1);*/


        //文件上傳原理
        InputStream is = request.getInputStream();//這是文件上傳的原理
        byte []buffer = new byte[1024];
        int len=-1;
        while((len=is.read(buffer))!=-1){
            System.out.println(new String(buffer,0,len));
        }

        /*Content-Type: multipart/form-data; boundary=---------------------------7de2192e140922
Accept-Encoding: gzip, deflate
Host: localhost:8080
Content-Length: 971
DNT: 1
Connection: Keep-Alive
Cache-Control: no-cache
Cookie: JSESSIONID=D8C093F784D359A1395BF097CD6E8B9A

-----------------------------7de2192e140922
Content-Disposition: form-data; name="f1"; filename="oracleinfo.txt"
Content-Type: text/plain

Enterprise Manager Database Control URL - (orcl2) :http://wangli-PC:1158/em數據庫配置文件已經安裝到 D:\oracle\product\10.2.0,同時其他選定的安裝組件也已經安裝到 D:\oracle\product\10.2.0\db_3。iSQL*Plus URL 爲:http://wangli-PC:5560/isqlplusiSQL*Plus DBA URL 爲:http://wangli-PC:5560/isqlplus/dba


^list\[\d+\]\.name
-----------------------------7de2192e140922
Content-Disposition: form-data; name="f2"; filename="oracleinfo.txt"
Content-Type: text/plain

Enterprise Manager Database Control URL - (orcl2) :http://wangli-PC:1158/em數據庫配置文件已經安裝到 D:\oracle\product\10.2.0,同時其他選定的安裝組件也已經安裝到 D:\oracle\product\10.2.0\db_3。iSQL*Plus URL 爲:http://wangli-PC:5560/isqlplusiSQL*Plus DBA URL 爲:http://wangli-PC:5560/isqlplus/dba


^list\[\d+\]\.name
-----------------------------7de2192e140922--
*/


    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.doGet(request, response);

    }

}

測試1:


測試2:


關於我們客戶端上傳到服務器時的信息,解析的工作已經有公司給我們做好了框架,我們直接用好了:SmartUpload、commons-FileUpload(主講)

要使用的時候也需要前提準備工作

3、當表單提交數據時,

enctype="application/x-www-form-urlencoded",它是默認值,此時服務器可以用request.getParameter()取數據,否則不能取數據必須把form的enctype屬值設爲multipart/form-data.設置該值後,瀏覽器在上傳文件時,將把文件數據附帶在http請求消息體中,並使用MIME協議對上傳的文件進行描述,以方便接收方對上傳數據進行解析和處理。

創建頁面

    如果表單的提交類型爲multipart/form-data,那麼表單的數據將不能通過傳統方式獲得。如何獲得:

4、接收客戶端數據並引入上傳框架

5、框架的使用

1、介紹SmartUpload  好用,但已經不更新了
2、Commons-FileUpload(主講)

6、commons-fileupload框架的使用

1、導2個jar包
    commons-fileupload-xxx.jar
    commons-io-xxx.jar

    怎麼用框架呢?

2、文件上傳的步驟

    1、設置文件上傳所保存的文件夾
    file.mkdirs();//和mkdir()的區別是s可以創建多級目錄
    2、判斷是否爲enctype=enctype="multipart/form-data" 

    3、生成文件上傳對象
    在文檔裏拷貝代碼(開源上傳文件框架)
    4、通過文件上傳對象,轉化用戶請求,以得到文件域中的值對象

    5、遍歷各文件域對象,再取值
    另外:在上傳文本框上輸入文字不出現亂碼


    普通字段中文值:FileItem.getString("UTF-8");
    遍歷中加上else語句去判斷上傳字段的各種情況/或者用來限制上傳的文件類型,文件名的路徑也可能產生問題,加上解決代碼

    出現同名問題:
    總之:在遍歷的過程中考慮服務器會出現的9個問題的解決方法!!


    以上步驟寫入服務器硬盤時用到了IOUtils的便捷功能。

FileUploadServlet2.java

package com.itheima.servlet;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

import javax.servlet.ServletException;
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.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.IOUtils;

public class FileUploadServlet2 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");

        //文件上傳的步驟
        //1.設置文件上傳所保存的文件夾
        String storePath = getServletContext().getRealPath("/files");
        File file = new File(storePath);
        if(!file.exists()){
            //如果文件夾不存在,就調用 DOS命令創建文件夾
            file.mkdirs();//可以創建多級目錄
        }
        //2.判斷是否爲enctype="multipart/form-data"
        boolean isMultipart = ServletFileUpload.isMultipartContent(request);
        if(!isMultipart){
            //不是enctype="multipart/form-data"
            response.getWriter().write("你有病 ,沒腦子,剛說了enctype=multipart/form-data,2秒後請重新上傳");
            response.setHeader("Refresh", "2;URL="+request.getContextPath());
            return;
        }
        //3.生成文件上傳對象
        FileItemFactory factory = new DiskFileItemFactory();
        ServletFileUpload upload = new ServletFileUpload(factory);

        //4.通過文件上傳對象,轉化用戶請求,以得到各文件域的值對象
        List<FileItem> items =null;
        try {
            items = upload.parseRequest(request);
        } catch (FileUploadException e) {
            e.printStackTrace();
        }
        //5.遍歷各文件域對象,再取值
        for(FileItem item :items){
            if(item.isFormField()){
                //這是普通字段
                String name = item.getFieldName();//取框的name屬性
                String value = item.getString();//取框的值
                System.out.println(name+","+value);
            }else{
                //文件上傳字段  <input type="file>
                String fileName = item.getName();//  C:\Users\wangli\Desktop\Hib二級緩存.txt  注意有些瀏覽器只有文件名沒有路徑
                String trueFileName = fileName.substring(fileName.lastIndexOf(File.separator)+1);

                //得到上傳的文件內容
                InputStream is = item.getInputStream();
                OutputStream os = new FileOutputStream(storePath+File.separator+trueFileName);

                IOUtils.copy(is, os);
                os.close();
                is.close();
            }
        }
        response.getWriter().write("文件上傳成功!");
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.doGet(request, response);

    }

}

測試1:


測試2:


測試3:


測試4:


7、文件上傳的9個問題

1、如何保證服務器的安全

在01.jsp里加入一些關鍵性代碼:操作服務器的dos控制檯
解決:把保存文件的目錄放在WEB-INF目錄下,因爲tomcat服務器的這個目錄不對外開放。

2、臨時文件夾的問題

FileUploadServlet3裏設置臨時文件夾。

測試:在index.jsp裏的目的地走FileUploadServlet3上傳東西(大一些的文件);然後在臨時文件夾裏查看

當上傳完了,temp的文件還沒有去除掉。可以在代碼裏去添加
//用於刪除上傳中產生的臨時文件
item.delete();

3、如果上傳的文件是中文名怎麼辦?

a.中文的文件名:request.setCharacterEncoding("UTF-8");//專門用於解決上傳文件的文件名是中文的情況。

另外:在上傳文本框上輸入文字不出現亂碼


b.普通字段中文值:FileItem.getString("UTF-8");

4、防止同一個文件夾的文件重名

如果不處理--->導致文件被覆蓋
給文件名+UUID
在FileUploadServlet3里加上代碼

5、文件夾的內容過多

在FileUploadServlet3里加上代碼
    a、按時間分類
    b、引入hashCode碼實現生成子文件夾


測試時注意serlvet裏的代碼重載來測試!!!!

6、上傳文件的大小

繼續在FileUploadServlet3里加上代碼測試

測試會在服務器裏提示客戶端的錯誤操作。服務器正常運行。

7、限制上傳文件的類型

判斷文件的MIME類型:image/jpg  text/html   ....

繼續在FileUploadServlet3里加上代碼測試

8、多文件上傳時,用戶沒傳全

防止一些文件域沒有上傳文件:

9、文件上傳進度條:異步與服務器進行通信,間隔性的通信

加入監聽上傳文件的進度:代碼

直接調用jar包的監聽器

實現進度條(課下興趣)

FileUploadServlet3.java

package com.itheima.servlet;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import javax.servlet.ServletException;
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;
import org.apache.commons.io.IOUtils;

public class FileUploadServlet3 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");//專門用於解決上傳文件的文件名爲中文的情況
        response.setContentType("text/html;charset=UTF-8");

        //文件上傳的步驟
        //1.設置文件上傳所保存的文件夾
        String storePath = getServletContext().getRealPath("/WEB-INF/files");
        File file = new File(storePath);
        if(!file.exists()){
            //如果文件夾不存在,就調用 DOS命令創建文件夾
            file.mkdirs();//可以創建多級目錄
        }

        //2.判斷是否爲enctype="multipart/form-data"
                boolean isMultipart = ServletFileUpload.isMultipartContent(request);
                if(!isMultipart){
                    //不是enctype="multipart/form-data"
                    response.getWriter().write("你有病 ,沒腦子,剛說了enctype=multipart/form-data,2秒後請重新上傳");
                    response.setHeader("Refresh", "2;URL="+request.getContextPath());
                    return;
                }
        //3.生成文件上傳對象
            DiskFileItemFactory factory = new DiskFileItemFactory();
            factory.setRepository(new File("e:/h47"));//設置臨時文件保存的文件夾
            factory.setSizeThreshold(50*1024*1024);//50M



            ServletFileUpload upload = new ServletFileUpload(factory);

            //監聽上傳文件的進度
            /*upload.setProgressListener(new ProgressListener() {

                public void update(long readed, long length, int arg2) {
                    System.out.println("當前上傳的進度:"+readed*1.0/length);

                }
            });*/

            //限制上傳文件的大小
            /*upload.setFileSizeMax(2*1024*1024);//單個文件大小
            upload.setSizeMax(3*1024*1024);//總文件大小
*/          
            //4.通過文件上傳對象,轉化用戶請求,以得到各文件域的值對象
            List<FileItem> items =null;
            try {
                items = upload.parseRequest(request);
            } catch (FileUploadException e) {
                e.printStackTrace();
            }
            //5.遍歷各文件域對象,再取值
            for(FileItem item :items){
                if(item.isFormField()){
                    //這是普通字段
                    String name = item.getFieldName();//取框的name屬性
                    String value = item.getString("UTF-8");//取框的值  代表文本框的值沒有亂碼
                    System.out.println(name+","+value);
                }else{
                    String mimetype = item.getContentType();//MIME類型   image/jpg   text/html  text/js  text/css
                    if("".equals(item.getName())){
                        continue;//防止一些文件域沒有上傳文件
                    }
                    //if(mimetype.contains("image")){
                        try {
                            //文件上傳字段  <input type="file>
                            String fileName = item.getName();   //  C:\Users\wangli\Desktop\Hib二級緩存.txt  注意有些瀏覽器只有文件名沒有路徑
                            String trueFileName = fileName.substring(fileName.lastIndexOf(File.separator)+1);
                            String uuidTrueFileName = UUID.randomUUID().toString()+"_"+trueFileName;
                            //得到上傳的文件內容
                            InputStream is = item.getInputStream();

                            //加入子文件夾,避免一個文件夾下文件過多的問題
                            String path = createDir(storePath,uuidTrueFileName);
                            OutputStream os = new FileOutputStream(storePath+File.separator+path+File.separator+uuidTrueFileName);

                            IOUtils.copy(is, os);

                            //用於刪除上傳過程中,所產生的臨時文件

                            os.close();
                            is.close();
                            item.delete();
                        } catch (Exception e) {
                            e.printStackTrace();
                            response.getWriter().write("文件上傳失敗");
                        }
                    /*}
                    else{
                    //  response.getWriter().write("上傳文件類型不匹配");
                    }*/

                }
            }

            response.getWriter().write("文件上傳成功!");
    }

    //按時間區分
    public String createDir(String storePath){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddhhmmss");
        String path = sdf.format(new Date());
        File file = new File(storePath,path);
        if(!file.exists()){
            file.mkdirs();
        }
        return path;
    }
    //1010 0000 1111 0000 1010 0001
    //0000 0000 0000 0000 0000 1111     &0xf
    //0000 0000 0000 0000 0000 0001  ---------------->(0-15)


    //1010 0000 1111 0000 1010 0001
    //0000 0000 0000 0000 1111 0000   0xf0
    //0000 0000 0000 0000 1010 0000   >>4
    //0000 0000 0000 0000 0000 1010   --------------->(0-15)   兩級目錄,共有16*16=256個文件夾
    //引入hashCode碼實現生成子文件夾
    public String createDir(String storePath,String fileName){
        int code = fileName.hashCode();
        int dir1=code&0xf;//按位與
        int dir2= (code & 0xf0)>>4;//先進行位與,再進行右移4位
        String path = dir1+File.separator+dir2;
        File file = new File(storePath,path);
        if(!file.exists()){
            file.mkdirs();
        }
        return path;
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.doGet(request, response);
    }

}

解釋問題1:


解釋問題2:


解釋問題3:


解釋問題4:


解釋問題5:


解釋問題6:


解釋問題7:


解釋問題8:


解釋問題9:


解釋問題10:


解釋問題11:


二、文件下載功能演示

實驗:項目:day2002download

項目架構:


index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>

    <title>上傳</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="http://blog.163.com/faith_yee/blog/styles.css">
    -->
  </head>

  <body>
    <form action="${pageContext.request.contextPath}/servlet/UploadServlet1" enctype="multipart/form-data" method="post">
        用戶名:<input type="text" name="name"/><br/>
        靚照1:<input type="file" name="f1"/><br/>
        靚照2:<input type="file" name="f2"/><br/>
        <input type="submit" value="保存"/>
    </form>
  </body>
</html>

listFile.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>

    <title></title>

    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    

  </head>

  <body>
    <a href="http://blog.163.com/faith_yee/blog/${pageContext.request.contextPath}/index.jsp">繼續上傳</a>
    <hr/>
    <c:forEach items="${map}" var="me">
        <c:url value="/servlet/DownloadServlet" var="url">
            <c:param name="filename" value="${me.key}"></c:param>
        </c:url>
        ${me.value}&nbsp;&nbsp;<a href="http://blog.163.com/faith_yee/blog/${url}">下載</a><br/>
    </c:forEach>
  </body>
</html>

UploadServlet1.java

package com.itheima.servlet;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.UUID;

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

public class UploadServlet1 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");//只能處理中文文件名
        //1.要保證文件夾存在
        String storePath = getServletContext().getRealPath("/WEB-INF/files");
        File file = new File(storePath);
        if(!file.exists()){
            file.mkdirs();
        }
        //2.判斷是否爲enctype="multipart/form-data"
        boolean isMultipart = ServletFileUpload.isMultipartContent(request);
        if(!isMultipart){
            response.getWriter().write("2秒重新上傳");
            response.setHeader("Refresh", "2;URL="+request.getContextPath());
            return;
        }
        //3.生成文件上傳 對象
        DiskFileItemFactory factory = new DiskFileItemFactory();
        ServletFileUpload upload = new ServletFileUpload(factory);

        //4.轉化請求類型,得到List<FileItem>
        try {
            List<FileItem> list = upload.parseRequest(request);

            //5.遍歷
            for(FileItem item:list){
                if(item.isFormField()){
                    String name = item.getFieldName();
                    String value = item.getString("UTF-8");
                    System.out.println(name+":"+value);
                }else{
                    //上傳字段
                    if("".equals(item.getName())){
                        continue;
                    }
                    String mime = item.getContentType();
                    if(mime.contains("image")){
                        String fileName = item.getName();
                        fileName = fileName.substring(fileName.lastIndexOf(File.separator)+1);

                        String trueFileName = UUID.randomUUID().toString()+"_"+fileName;

                        //防一個文件夾下文件過多
                        String path = createDir(storePath,trueFileName);

                        //得到輸入流
                        InputStream is = item.getInputStream();
                        OutputStream os = new FileOutputStream(storePath+File.separator+path+File.separator+trueFileName);

                        IOUtils.copy(is, os);

                        //關流
                        os.close();
                        is.close();
                        item.delete();//刪除臨時文件
                    }
                }
            }
            //response.getWriter().write("文件上傳成功");
            //上傳成功後直接進入查詢文件列表的Servlet
            request.getRequestDispatcher("/servlet/ListFilesServlet").forward(request, response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public String createDir(String storePath,String fileName){
        int code = fileName.hashCode();
        int dir1=code&0xf;
        int dir2 = (code&0xf0)>>4;
        String path = dir1+File.separator+dir2;
        File file = new File(storePath,path);
        if(!file.exists()){
            file.mkdirs();
        }
        return path;
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.doGet(request, response);

    }

}

ListFilesServlet.java

package com.itheima.servlet;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ListFilesServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //1.找到WEB-INF/files的目錄
        String storepath = getServletContext().getRealPath("/WEB-INF/files");

        //2.要生成一個Map集合,用於存儲遞歸遍歷過程中得到文件(key:UUID_文件名,value:原來的文件名)
        Map<String,String> map = new HashMap<String,String>();

        //3.遞歸得到文件名
        treeWalk(new File(storepath),map);

        //4.保存到request域
        request.setAttribute("map", map);

        //5.轉發
        request.getRequestDispatcher("/listFiles.jsp").forward(request, response);
    }

    //遞歸遍歷文件夾
    private void treeWalk(File file, Map<String, String> map) {
        if(file.isFile()){
            String fileName = file.getName();//得到文件名  UUID_文件名
            String oldFileName = fileName.split("_")[1];//得到原始文件名
            map.put(fileName, oldFileName);
        }else{
            File [] childFiles = file.listFiles();//列舉出當前文件夾下的所有文件及子文件夾
            for(File childFile: childFiles){
                treeWalk(childFile,map);
            }
        }
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.doGet(request, response);

    }

}

DownloadServlet.java

package com.itheima.servlet;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;

public class DownloadServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        //1.取參數
        String fileName = request.getParameter("filename");
        fileName= new String(fileName.getBytes("iso-8859-1"),"UTF-8");

        //得到原始文件名
        String oldFileName = fileName.split("_")[1];
        //2.
        //2.1.找到WEB-INF/files的目錄
        String storepath = getServletContext().getRealPath("/WEB-INF/files");
        //2.2找這個文件的原始路徑
        String path = createDir(storepath,fileName);

        //3.得到真正的文件的文件流     /WEB-INF/files/1/0/fdsfdsfsdfdsfs_a.jpg
        InputStream is = new FileInputStream(storepath+File.separator+path+File.separator+fileName);

        //4.設置響應頭
        response.setHeader("Content-Disposition", "attachment;filename="+URLEncoder.encode(oldFileName,"UTF-8"));
        //5.下載
        OutputStream os =response.getOutputStream();
        IOUtils.copy(is, os);

        is.close();

        os.write(("文件下載成功!<a href='http://blog.163.com/faith_yee/blog/"+request.getContextPath()+"/servlet/ListFilesServlet'>繼續下載</a>").getBytes("UTF-8"));

    }
    public String createDir(String storePath,String fileName){
        int code = fileName.hashCode();
        int dir1=code&0xf;
        int dir2 = (code&0xf0)>>4;
        String path = dir1+File.separator+dir2;

        return path;
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.doGet(request, response);

    }

}

上傳文件:


列出服務器接收的文件:


點擊下載文件:


在服務器上記錄上傳的用戶名:


UploadServlet1.java:演示文件上傳代碼

在代碼里加入上傳成功後查詢所有文件列表

ListFilesServlet.java:把上傳到服務器的文件展示出來的servlet:ListFileServlet:用來獲得文件列表並存儲在map中提供給listFile.jsp去獲取文件然後提供給用戶下載,之後會提供鏈接跳到另外一個servlet去處理用戶的下載。

1、找到WEB-INF/files的目錄
String storepath = getSetvletContext().getRealPath("/WEB-INF/files");

    1.1得到原始文件名
2、要生成一個Map集合,用於存儲遞歸遍歷過程中得到的文件(Key:UUID_文件名,value:原來的文件名)
Map <String ,String> map = new HashMap<String , String>();
3、遞歸得到文件名
treeWalk(new File(storepath),map);//創建這個函數,找到了文件夾然後把內容保存在了Map集合中了
4、保存到request域中
request.setAttribute("map",map);

5、轉發--->listFile.jsp
真實從服務器下載的是UUID文件名的文件,即從key中拿內容,和給用戶的文件名是從map的value中拿取。

//遞歸遍歷文件夾
填充treeWalk()函數。
 遞歸文件夾


DownloadServlet.java:處理map中的文件給用戶下載

1、取參數--->拿到文件名

2、找這個文件的原始路徑,使用createDir()
    2.1、找到WEB-INF/files的目錄
    2.2、找這個文件的原始路徑

3、得到真正的文件的文件流

4、設置響應頭

5、下載

三、郵件發送接收原理


練習:手工發送一封郵件(熟悉SMTP協議) 準備:

[email protected] iamsorry

itheimacloud     aXRoZWltYWNsb3Vk
iamsorry    aWFtc29ycnk=

smtp.163.com
pop.163.com

開始發送:
telnet smtp.163.com 25
---------------------------------以下屬於SMTP協議的內容
ehlo wyj 加空格          向服務器打招呼

auth login             請求認證

aXRoZWltYWNsb3Vk

aWFtc29ycnk=

mail from:<[email protected]>
rcpt to:<[email protected]>

data               標識郵件內容開始(內容需要遵守一定的格式:RFC822規範)
from:[email protected]
to:[email protected]
subject:this is test mail

aaaaaaaaaaaaaaa
bbbbbbbbbbbbbbb
.                   <CR><LF>.代表結束 
----------------------------------
quit

郵件賬號:


dos輸入代碼:



收到郵件


四、使用JavaMail (熟悉就好,面試少)

目標:註冊成功後發送一封激活郵件,可以進行激活用戶

JavaMail API:規範  ()
依賴兩jar包
jaf-1_1_1.zip
javamail1_4_4.zip

實驗:項目:day2003mail

項目架構:


MailTest.java

package com.itheima.test;

import java.net.InetAddress;
import java.util.Properties;

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

public class MailTest {

    /**
     * @param args
     */
    public static void main(String[] args) {
        try {
            Properties p = new Properties();
            p.put("mail.transport.protocol", "smtp");
            p.put("mail.smtp.host", "smtp.163.com");

            Session session = Session.getInstance(p);
            session.setDebug(true);
            //2.得到Message
            MimeMessage message = new MimeMessage(session);
            message.setFrom(new InternetAddress("[email protected]"));
            message.setRecipients(Message.RecipientType.TO, "[email protected]");
            message.setSubject("這是來自百合網的一個姑娘寫來的郵件");
            message.setText("大哥,小妹今年18歲,未婚,。。。。。。。");

            //發送
            Transport tp = session.getTransport();
            tp.connect("itheimacloud", "iamsorry");
            tp.sendMessage(message, message.getAllRecipients());

            tp.close();
        } catch (AddressException e) {
            e.printStackTrace();
        } catch (MessagingException e) {
            e.printStackTrace();
        }

    }

}

輸出結果:

DEBUG: setDebug: JavaMail version 1.4.4
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc]
DEBUG SMTP: useEhlo true, useAuth false
DEBUG SMTP: trying to connect to host "smtp.163.com", port 25, isSSL false
220 163.com Anti-spam GT for Coremail System (163com[20121016])
DEBUG SMTP: connected to host "smtp.163.com", port: 25

EHLO yw
250-mail
250-PIPELINING
250-AUTH LOGIN PLAIN
250-AUTH=LOGIN PLAIN
250-coremail 1Uxr2xKj7kG0xkI17xGrU7I0s8FY2U3Uj8Cz28x1UUUUU7Ic2I0Y2UFhzBbSUCa0xDrUUUUj
250-STARTTLS
250 8BITMIME
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "AUTH", arg "LOGIN PLAIN"
DEBUG SMTP: Found extension "AUTH=LOGIN", arg "PLAIN"
DEBUG SMTP: Found extension "coremail", arg "1Uxr2xKj7kG0xkI17xGrU7I0s8FY2U3Uj8Cz28x1UUUUU7Ic2I0Y2UFhzBbSUCa0xDrUUUUj"
DEBUG SMTP: Found extension "STARTTLS", arg ""
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Attempt to authenticate
DEBUG SMTP: check mechanisms: LOGIN PLAIN DIGEST-MD5 NTLM 
AUTH LOGIN
334 dXNlcm5hbWU6
aXRoZWltYWNsb3Vk
334 UGFzc3dvcmQ6
aWFtc29ycnk=
235 Authentication successful
DEBUG SMTP: use8bit false
MAIL FROM:<[email protected]>
250 Mail OK
RCPT TO:<[email protected]>
250 Mail OK
DEBUG SMTP: Verified Addresses
DEBUG SMTP:   [email protected]
DATA
354 End data with <CR><LF>.<CR><LF>
From: [email protected]
To: [email protected]
Message-ID: <27994366.0.1415631421186.JavaMail.Administrator@yw>
Subject: =?GBK?B?1eLKx8C019Sw2brPzfi1xNK7uPa5w8Tv0LTAtLXE08q8/g==?=
MIME-Version: 1.0
Content-Type: text/plain; charset=GBK
Content-Transfer-Encoding: base64

tPO456Os0KHDw73xxOoxOMvqo6zOtLvpo6yho6GjoaOho6GjoaOhow==
.
250 Mail OK queued as smtp11,D8CowEA5IhKj0mBUDPN9AQ--.1352S2 1415631524
QUIT
221 Bye

收件成功:


資料下載

發佈了81 篇原創文章 · 獲贊 4 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章