天天看點

Servlet的相關知識(以檔案上傳為例)

init方法隻執行一次。

<init-param>
            <description>初始化參數(這裡僅僅隻是測試)</description>
            <param-name>baseDir</param-name>
            <param-value>D:\\app</param-value>
        </init-param>
           

通路初始化參數的方法。

baseFileDir = this.getInitParameter("baseDir");
           

這樣的話 baseFileDir 就會顯示:

baseFileDir :   D:\\app
           

Windows 平台的路徑斜杠符号:

\resources\upload\

控制台的輸出:

Servlet 的 init 方法:隻在該 servlet 初始化的時候執行一次。
執行了圖檔檔案上傳的 init 方法

private static String baseFileDir =  File.separator + "resources" + File.separator + "upload" + File.separator;//上傳檔案存儲目錄
baseFileDir :   \resources\upload\

String realBaseDir = this.getServletConfig().getServletContext().getRealPath(baseFileDir);
真實的基本路徑(隻是一個路徑)realBaseDir: 
D:\ws\company\langying\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\lyadmin\resources\upload
           

name=2015-02-01_225159.jpg

StoreLocation=C:\Users\ADMINI~1\AppData\Local\Temp\upload_b2294c8d_d41f_4041_809f_1ea1975ecdef_00000000.tmp

size=51275 bytes

isFormField=false

FieldName=filedata

Servlet的相關知識(以檔案上傳為例)

先貼一段控制台的輸出:

執行了圖檔檔案上傳的 init 方法
本類的 baseFileDir 屬性已經被指派 \resources\upload\
本類的 maxSize 屬性已經被指派 0
baseFileDir :   \resources\upload\
真實的基本路徑(隻是一個路徑)realBaseDir: D:\ws\company\langying\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\lyadmin\resources\upload
item.getFieldName() 方法的傳回值:filedata
fileNameLong:2015-02-01_225159.jpg
上傳檔案的擴充名 extensionName :    jpg
這裡開始拼接上傳以後的檔案路徑(帶日期格式的)saveDirPath: \resources\upload\20150319/
檔案存儲在容器中的絕對路徑 saveFilePath :    D:\ws\company\langying\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\lyadmin\resources\upload\20150319/
request.getScheme() http
request.getServerName() localhost
request.getServerPort() 8080
request.getContextPath()    /lyadmin
newFileName:    http://localhost:8080/lyadmin/resources/upload/20150319/15b64a88-0c5a-49a8-bda4-acc66ce43790.jpg
           
// xbhEditor 編輯器圖檔上傳回調函數
        function insertUpload(msg) {
            var _msg = msg.toString();
            alert(_msg);
            var _picture_name = _msg.substring(_msg.lastIndexOf("/")+);
            var _picture_path = Substring(_msg);
            var _str = "<input type='checkbox' name='_pictures' value='"+_picture_path+"' checked='checked' onclick='return false'/><label>"+_picture_name+"</label><br/>";
            $("#xh_editor").append(_msg);
            $("#uploadList").append("上傳圖檔産生的流水号:" + _str);
        }
           
Servlet的相關知識(以檔案上傳為例)
Servlet的相關知識(以檔案上傳為例)
Servlet的相關知識(以檔案上傳為例)

封裝的一個小例子(參考了網上其他網友寫的,非原創):

package com.writing.manager.servlet;

import org.apache.log4j.Logger;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
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.DiskFileUpload;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;

import com.writing.manager.util.GetDataConfUtil;

@SuppressWarnings({ "serial", "deprecation" })
public class UploadFileServlet extends HttpServlet {
    /**
     * Logger for this class
     */
    private static final Logger logger = Logger.getLogger(UploadFileServlet.class);

    private static String baseFileDir =  File.separator + "resources" + File.separator + "upload" + File.separator;//上傳檔案存儲目錄
    private static String baseURLDir = "/resources/upload/";//上傳檔案目錄URL
    private static String fileExt = "jpg,jpeg,bmp,gif,png";
    private static Long maxSize = l;

    // 0:不建目錄; 1:按天存入目錄 ;2:按月存入目錄;3:按擴充名存目錄。建議使用按天存。
    private static String dirType = "1";

    /**
     * 檔案上傳初始化工作(隻執行一次)
     */
    public void init() throws ServletException {
        logger.debug("執行了圖檔檔案上傳的 init 方法");
        logger.debug("本類的 baseFileDir 屬性已經被指派\t" + baseFileDir);
        logger.debug("本類的 maxSize 屬性已經被指派\t" + maxSize);

        // 擷取檔案上傳存儲的相對路徑, this.getInitParameter 表示從  web.xml 配置檔案中擷取
        // 如果初始化的參數裡面沒有配置 baseDir,就取本類 servlet 的 baseFileDir 執行個體屬性
        if (!StringUtils.isBlank(this.getInitParameter("baseDir"))){
            baseFileDir = this.getInitParameter("baseDir");
        }

        logger.debug("baseFileDir :\t" + baseFileDir);

        /**
         * 這個方法常用,必須記住
         */
        String realBaseDir = this.getServletConfig().getServletContext().getRealPath(baseFileDir);
        logger.debug("真實的基本路徑(隻是一個路徑)realBaseDir:\t" + realBaseDir);
        // 把真實的實體路徑放在一個 File 類裡面,包裝成 File 對象,
        // 實作的業務邏輯是:如果這個目錄不存在,就讓 Java 幫你建立一下這個路徑
        File baseFile = new File(realBaseDir);
        if (!baseFile.exists()) {
            baseFile.mkdir();
        }
        // 擷取檔案類型參數*
        fileExt = this.getInitParameter("fileExt");
        if (StringUtils.isBlank(fileExt)){
            fileExt = "jpg,jpeg,gif,bmp,png";
        } 
        // 擷取檔案大小參數
        String maxSize_str = this.getInitParameter("maxSize");
        if (StringUtils.isNotBlank(maxSize_str)) {
            maxSize = new Long(maxSize_str);
        }
        // 擷取檔案目錄類型參數
        // 下面寫的幾句代碼的作用是:在參數的配置不正确或者不規範的前提下, dirType 選擇按天存入目錄
        dirType = this.getInitParameter("dirType");
        if (StringUtils.isBlank(dirType)){
            dirType = "1";
        }
        if (",0,1,2,3,".indexOf("," + dirType + ",") < ){
            dirType = "1";
        }
    }

    /**
     * 上傳檔案資料處理過程
     */
    @SuppressWarnings({"unchecked" })
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html; charset=UTF-8");
        response.setHeader("Cache-Control", "no-cache");
        /**
         * 傳回給前台頁面的參數 err 錯誤消息
         */
        String err = "";
        /**
         * 傳回一個能正确通路的 URL
         */
        String newFileName = "";
        DiskFileUpload upload = new DiskFileUpload();
        try {
            List<FileItem> items = upload.parseRequest(request);
            Map<String, Serializable> fields = new HashMap<String, Serializable>();
            Iterator<FileItem> iter = items.iterator();
            while (iter.hasNext()) {
                FileItem item = (FileItem) iter.next();
                logger.debug("item.getFieldName() 方法的傳回值:" + item.getFieldName());
                if (item.isFormField()){
                    fields.put(item.getFieldName(), item.getString());
                }else{
                    fields.put(item.getFieldName(), item);
                }
            }

            // 擷取表單的上傳檔案,這是一個重要的對象
            FileItem uploadFile = (FileItem)fields.get("filedata");
            // 擷取檔案上傳路徑名稱*
            String fileNameLong = uploadFile.getName();
            logger.debug("fileNameLong:" + fileNameLong);

            // 擷取檔案擴充名
            // 索引加 1 的效果是隻取 xxx.jpg 的jpg,而不帶 “.” 号
            String extensionName = fileNameLong.substring(fileNameLong.lastIndexOf(".") + );
            logger.debug("上傳檔案的擴充名 extensionName :\t" + extensionName);
            // 檢查上傳檔案的檔案類型
            if (("," + fileExt.toLowerCase() + ",").indexOf("," + extensionName.toLowerCase() + ",") < ){
                printInfo(response, "不允許上傳此類型的檔案", "");
                return;
            }
            // 檔案是否為空
            if (uploadFile.getSize() == ){
                printInfo(response, "上傳檔案不能為空", "");
                return;
            }
            // 檢查檔案大小(這一句判斷有問題)
            if (maxSize >  && uploadFile.getSize() > maxSize){
                printInfo(response, "上傳檔案的大小超出限制", "");
                return;
            }

            // 0:不建目錄; 1:按天存入目錄 ;2:按月存入目錄;3:按擴充名存目錄。建議使用按天存。
            String fileFolder = "";
            if (dirType.equalsIgnoreCase("1")){
                fileFolder = new SimpleDateFormat("yyyyMMdd").format(new Date());;
            }
            if (dirType.equalsIgnoreCase("2")){
                fileFolder = new SimpleDateFormat("yyyyMM").format(new Date());
            }
            if (dirType.equalsIgnoreCase("3")){
                fileFolder = extensionName.toLowerCase();
            }

            logger.debug("fileFolder 的值為:\t" + fileFolder);

            /**
             * 我們的思路,先拼目錄,再拼檔案
             */
            // 檔案存儲的相對路徑(這裡開始拼接上傳以後的檔案路徑)
            String saveDirPath = baseFileDir + fileFolder + File.separator;
            logger.debug("這裡開始拼接上傳以後的檔案路徑(帶日期格式的)saveDirPath:\t" + saveDirPath );

            // 檔案存儲在容器中的絕對路徑
            String saveFilePath = this.getServletConfig().getServletContext().getRealPath("") + baseFileDir + fileFolder + File.separator;
            logger.debug("檔案存儲在容器中的絕對路徑 saveFilePath :\t" + saveFilePath);


            // 建構檔案目錄以及目錄檔案*
            File fileDir = new File(saveFilePath);
            if (!fileDir.exists()) {
                fileDir.mkdirs();
            }

            // 檔案重命名(使用 UUID 檔案名不會重複)
            String filename = UUID.randomUUID().toString();
            File savefile = new File(saveFilePath + filename + "." + extensionName);
            logger.debug("封裝到 File 類裡面的重要路徑和檔案名:" + saveFilePath + filename + "." + extensionName);

            /**
             *  
             *  【【【【【【這是儲存檔案的重要方法, uploadFile 是核心對象,write 的參數是一個 File 類型的檔案 】】】】】】
             *  存儲上傳檔案(這個方法非常重要,執行了這個方法以後,檔案就被儲存在這個真實的路徑裡面了)
             *  注意:該方法隻能使用一次。
             */
            uploadFile.write(savefile);
            // uploadFile.write(new File("D:\\opt\\fileupload\\1.jpg"));

            // commons io 包的重要方法:拷貝檔案到一個路徑,即使這個路徑不存在, commons io 也會幫你建立好

            // Windows 本機作業系統可以這樣寫,如果是 Linux 系統的話,應該按照下面的寫法

            String dir_prefix =GetDataConfUtil.getPropertyValue("fileupload", "dir.prefix");
            FileUtils.copyFileToDirectory(savefile, new File(dir_prefix + File.separator + fileFolder));


            logger.debug("request.getScheme()\t" + request.getScheme());
            logger.debug("request.getServerName()\t" + request.getServerName());
            logger.debug("request.getServerPort()\t" + request.getServerPort());
            logger.debug("request.getContextPath()\t" + request.getContextPath());

            String projectBasePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath();

            // 未使用公司的檔案伺服器,即把圖檔存放在自己項目下的檔案通路路徑
            // newFileName = projectBasePath + baseURLDir + fileFolder + "/" + filename + "." + extensionName;      

            // 使用了公司的檔案伺服器,通路的位址
            newFileName = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "/create_pdf/getfile/suggest/" + fileFolder + "/" + filename + "." + extensionName;                                

            logger.debug("通過浏覽器可以通路到的:\t" + newFileName);

        } catch (Exception ex) {
            logger.error("上傳圖檔檔案的過程中發現異常:" + ex.getMessage());
            newFileName = "";
            err = "錯誤: " + ex.getMessage();
        }
        printInfo(response, err, newFileName);
    }

    /**
     * 使用 IO 流輸出 json格式的資料
     * @param response
     * @param err
     * @param newFileName
     * @throws IOException
     */
    public void printInfo(HttpServletResponse response, String err, String newFileName) throws IOException {
        PrintWriter out = response.getWriter();
        // String filename = newFileName.substring(newFileName.lastIndexOf("/") + 1);
        out.println("{\"err\":\"" + err + "\",\"msg\":\"" + newFileName + "\"}");
        out.flush();
        out.close();
    }
}
           

繼續閱讀