您的位置:首页 > 其它

Servlet的相关知识(以文件上传为例)

2015-03-19 21:07 429 查看
init方法只执行一次。

[code]    <init-param>
            <description>初始化参数(这里仅仅只是测试)</description>
            <param-name>baseDir</param-name>
            <param-value>D:\\app</param-value>
        </init-param>


访问初始化参数的方法。

[code]baseFileDir = this.getInitParameter("baseDir");


这样的话 baseFileDir 就会显示:

[code]baseFileDir :   D:\\app


Windows 平台的路径斜杠符号:

\resources\upload\

控制台的输出:

[code]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



先贴一段控制台的输出:

[code]执行了图片文件上传的 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[/code] 
[code]        // xbhEditor 编辑器图片上传回调函数
        function insertUpload(msg) {
            var _msg = msg.toString();
            alert(_msg);
            var _picture_name = _msg.substring(_msg.lastIndexOf("/")+1);
            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);
        }











封装的一个小例子(参考了网上其他网友写的,非原创):

[code]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 = 0l;

    // 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 + ",") < 0){
            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(".") + 1);
            logger.debug("上传文件的扩展名 extensionName :\t" + extensionName);
            // 检查上传文件的文件类型
            if (("," + fileExt.toLowerCase() + ",").indexOf("," + extensionName.toLowerCase() + ",") < 0){
                printInfo(response, "不允许上传此类型的文件", "");
                return;
            }
            // 文件是否为空
            if (uploadFile.getSize() == 0){
                printInfo(response, "上传文件不能为空", "");
                return;
            }
            // 检查文件大小(这一句判断有问题)
            if (maxSize > 0 && 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();
    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: