文件的上傳(如何兼容火狐與IE)與國際化的原理


1.文件的上傳
    [1] 簡介
        > 將本地的文件上傳到服務器中
        > 用戶需要通過一個表單將文件上傳到服務器中
 
    [2] 表單的設置
        > 上傳文件時需要使用input表單項,input的type時file。
        > 上傳文件的表單一定要是post請求。
        > 在表單中還有一個屬性:
            enctype,使用它來指定如何處理請求體,它的默認值是application/x-www-form-urlencoded。
            他的意思是請求體會被URL編碼,而我們上傳文件時上傳的是文件流,它是不需要被編碼的
        > 在上傳文件時enctype屬性必須設置為:multipart/form-data
            它表示將我們的表單設置為一個多部件的表單,當表單設置為該值時,那么我們的一個表單項會作為一個部件,發送到服務器。
                當使用多部件表達式,請求體會使用類似這樣的-----------------------------7e01ce2921096c分割符來分割。
        > 當表單設置為多部件表單以后,我們的request.getParameter()就廢了。       
 
    [3] FileUpload
        > commons-fileupload
        > commons-fileupload是Apache出的一款專門用來處理文件上傳的工具,
            使用它可以自動去解析多部件表單。
        > commons-fileupload依賴於commons-io
        > 使用它需要導入兩個jar包:
            commons-fileupload-1.3.1.jar
            commons-io-1.4.jar
        > 核心類:
            DiskFileItemFactory
                - 工廠類,用來構建解析器
            ServletFileUpload
                - 解析器類,用來解析請求報文
            FileItem
                - 解析器將解析到的內容封裝為FileItem對象
                - 方法:
                    boolean isFormField() --> 判斷當前表單項是否是普通表單項,如果是普通表單項返回true,否則返回false
                    String getContentType() --> 獲取文件的類型,返回是一個MIME值
                    String getFieldName() --> 獲取表單項的name屬性值
                    String getName() --> 獲取上傳文件的名字
                    long getSize() --> 獲取文件的大小(字節)
                    String getString(String encoding) --> 獲取用戶填寫value值,需要傳一個字符集
                    void write(File file) --> 將文件寫入磁盤中
 
        > 如何使用:
            1.獲取工廠類實例
            2.獲取解析器類實例
            3.解析請求報文獲取FileItem對象
 
    [4] 細節
        >  部分瀏覽器在上傳文件時,文件名使用的是文件的絕對路徑。
            而在保存文件時,使用絕對路徑會出現問題,文件不能正常寫入到服務器中。
        > 所以這種情況我們需要做一些處理:
            C:\asd\zxc\Desktop\qwe\ert\rrrr.jpg
            所以這種文件名,我們需要對它進行截取字符串的操作,從最后一個\以前的內容全都不要
 
        > 當我們上傳文件時,很有可能多個用戶上傳同名文件,這樣會導致后上傳的文件覆蓋舊文件,
            我們可以為圖片添加一個唯一的標識作為前綴:唯一標識_rrrr.jpg。
            這里我們的唯一標識使用UUID
 
        > 文件大小的限制
            - 限制文件大小的操作,都是通過解析器對象ServletFileUpload來進行
            1.單個文件大小的限制
                - 限制文件大小為60kb
                    fileUpload.setFileSizeMax(1024*60);
                - 當上傳的文件超過限制,程序會拋出異常:
                    FileSizeLimitExceededException
                - 我們可以對該異常進行捕獲,然后顯示一個錯誤消息   
 
            2.文件總大小的限制
                - 限制文件總大小為150KB
                    fileUpload.setSizeMax(1024*150);
                - 當上傳文件的總大小超標是,會拋出如下異常:
                    SizeLimitExceededException
                - 我們可以對該異常進行捕獲,然后顯示一個錯誤消息   
 
2.文件的下載
    [1] 簡介
        > 將服務器中的文件下載到本地
        > 下載文件很簡單,直接把文件放到服務器中,然后為瀏覽器提供一個超鏈接即可,
            但是如果瀏覽器支持當前文件格式,瀏覽器會自動打開文件,不會直接下載。
        > 如果將文件直接放到服務器中,當用戶下載文件時不會有任何的限制,不能去檢查用戶的權限。
            所以一般我們下載時我們將文件放到WEB-INF文件夾下,讓用戶通過訪問一個Servlet來進行下載。
 
    [2] 下載所需要的內容
            1.獲取到文件的流
            2.設置兩個響應頭
 
    [3] 下載相關的兩個響應頭
        1) 文件類型 Content-Type --> 文件的MIME類型   
            - 下載的文件的類型,需要設置一個MIME值
            - 文件的MIME類型可以通過總的web.xml進行查詢
            - 我們也可以通過ServletContext的getMimeType()方法來獲取文件的MIME類型
 
        2) 下載文件的信息 Content-Disposition --> attachment; filename=文件名
            - Content-Disposition這個頭用來告訴瀏覽器如何處理文件
            - 值 attachment; filename=文件名,這個值就是告訴瀏覽器我發給你的是一個附件,請你下載
                filename用來指定文件的名字。
 
        3) 中文亂碼問題:
            > 在響應頭中不能直接設置中文,如果非得設置,必須對文件名進行url編碼。
                fileName = URLEncoder.encode(fileName, "utf-8");
                大部分瀏覽器可以采用以上方式
            > 但是FireFox它是使用Base64進行的編碼,所以如果是火狐,使用上述方式,依然不好使。
                火狐的編碼方式:fileName = "=?utf-8?b?"+new BASE64Encoder().encode(fileName.getBytes())+"?=";
            > 但是火狐的方式IE又不支持了,如果我們需要同時兼容這兩款瀏覽器,在設置編碼是必須做一個判斷,
                如果是IE瀏覽器,則使用 fileName = URLEncoder.encode(fileName, "utf-8");
                    如果是Firefox,則使用 fileName = "=?utf-8?b?"+new BASE64Encoder().encode(fileName.getBytes())+"?=";
            > 我們可以通過User-Agent的請求頭,來判斷瀏覽器的版本,如果頭中包含Firefox,則表示他是火狐。
            > 事例代碼:
                //判斷瀏覽器是否是火狐
                if(ua.contains("Firefox")){
                    //如果是火狐瀏覽器
                    fileName = "=?utf-8?b?"+new BASE64Encoder().encode(fileName.getBytes())+"?=";
                }else{
                    //其他瀏覽器
                    //對文件名進行編碼
                    //encode()需要兩個參數,第一個被編碼的字符串,第二個是使用的字符集
                    fileName = URLEncoder.encode(fileName, "utf-8");
                }
 
            > 還有一種方式,不太講理,誰問跟誰急
            > 先是用gbk為文件名進行編碼,再使用iso-8859-1進行解碼
                fileName = new String(fileName.getBytes("gbk"), "iso-8859-1");
            > 這種方式雖然簡單,但是有一些個別的字符會出問題。   
 
 
3.國際化(I18N)
    [1]國際化簡介
        > 國際化主要指我們的應用對不同國家和地區的語言的支持。
        > 國際化主要指支持英文。
 
    [2]核心類
        ResourceBundle
            - 負責管理國際化資源文件,根據不同的國家和地區的信息去加載不同的國際化資源文件
 
        Locale
            - locale負責表示國家地區和語言的信息
 
    [3]國際化的原理
        國際化資源文件:   
            > 國際化資源文件實際上就是一個properties文件,它配置的都是一些鍵值對結構
            > 國際化資源文件要求必須放到類路徑下(src)
            > 命名規則:基礎名_語言_國家.properties
 
        ResourceBundle會根據不同Locale信息,去加載不同的國際化資源文件,從而達到國際化的目的。
 
 
 
 
    [4]格式化標簽庫
        > 還可以使用JSTL中fmt標簽來完成國際化的操作。
        > 導入fmt標簽:
            <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>   
        > 常用標簽
            <fmt:setBundle basename="基礎名"/>
            <fmt:message key="屬性名" />
            <fmt:setLocale value="zh_CN"/>
            <fmt:formatDate value="<%=new Date() %>" type="both" dateStyle="full" timeStyle="full"/>
                value屬性:是被格式化的日期
                type屬性:日期的類型,date只顯示日期,time只顯示時間,both全都顯示
                dateStyle和timeStyle屬性:用來設置日期和時間的風格
                    可選值:full long medium short
        > 占位符:
            在國際化資源文件中可以指定帶占位符的信息,占位符從0開始,形式如下:
                WELCOME {0} TO OUR SITE, TODAY IS {1}
            在頁面中使用帶占位符的消息,需要在message標簽中插入param子標簽,
                param子標簽用來指定替換站位符的內容,
                    第一個param會替換所有的{0}
                    第二個會替換所有的{1}
                    以此類推
            例子:
                <fmt:message key="info">
                    <fmt:param>
                        <span style="color: red;">大師兄</span>
                    </fmt:param>
                    <fmt:param>
                        <span style="color: red;"><fmt:formatDate value="<%=new Date() %>" type="both" dateStyle="full" timeStyle="full"/></span>
                    </fmt:param>
                </fmt:message>
 

 

轉載請注明出處!

http://www.cnblogs.com/libingbin/

感謝您的閱讀。如果文章對您有用,那么請輕輕點個贊,以資鼓勵。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM