首页 > 代码库 > 文件上传与下载

文件上传与下载

 

前台:    1. 提交方式:post    2. 表单中有文件上传的表单项: <input type=”file” />    3. 指定表单类型:        默认类型:enctype="application/x-www-form-urlencoded"

 

文件上传类型:multipart/form-data

 

手动实现文件上传

<body>           <form name="frm_test" action="${pageContext.request.contextPath }/upload" method="post" enctype="multipart/form-data">            用户名:<input type="text" name="userName">  <br/>           文件:   <input type="file" name="file_img">   <br/>                      <input type="submit" value="注册">        </form>  </body>

 

 

public class UploadServlet extends HttpServlet {    public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        /*        request.getParameter(""); // GET/POST        request.getQueryString(); // 获取GET提交的数据         request.getInputStream(); // 获取post提交的数据   */                /***********手动获取文件上传表单数据************/                //1. 获取表单数据流        InputStream in =  request.getInputStream();        //2. 转换流        InputStreamReader inStream = new InputStreamReader(in, "UTF-8");        //3. 缓冲流        BufferedReader reader = new BufferedReader(inStream);        // 输出数据        String str = null;        while ((str = reader.readLine()) != null) {            System.out.println(str);        }                // 关闭        reader.close();        inStream.close();        in.close();    }

 

输出结果:------WebKitFormBoundaryGoQviatB7iM1dhPrContent-Disposition: form-data; name="userName"       【FileItem】Jack------WebKitFormBoundaryGoQviatB7iM1dhPrContent-Disposition: form-data; name="file_img"; filename="reamde.txt"Content-Type: text/plain                                     【FileItem】test!!!!!!!!!!!!!test!!!!!!!!!!!!!------WebKitFormBoundaryGoQviatB7iM1dhPr--
总结:
总结:最终获取数据,要对上面的结果进行解析!文件上传,在开发中经常用,每次都写解析程序!(工具类)也可以使用开源的文件上传组件-FileUpload组件!

 

FileUpload组件

Apache提供的文件上传组件:FileUpload组件

 

    1. 下载源码    2. 项目中引入jar文件            commons-fileupload-1.2.1.jar  【文件上传组件核心jar包】            commons-io-1.4.jar     【封装了对文件处理的相关工具类】

 

代码

public class UploadServlet extends HttpServlet {    // upload目录,保存上传的资源    public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {                /*********文件上传组件: 处理文件上传************/                        try {            // 1. 文件上传工厂            FileItemFactory factory = new DiskFileItemFactory();            // 2. 创建文件上传核心工具类            ServletFileUpload upload = new ServletFileUpload(factory);                    // 一、设置单个文件允许的最大的大小: 30M            upload.setFileSizeMax(30*1024*1024);            // 二、设置文件上传表单允许的总大小: 80M            upload.setSizeMax(80*1024*1024);            // 三、 设置上传表单文件名的编码            // 相当于:request.setCharacterEncoding("UTF-8");            upload.setHeaderEncoding("UTF-8");                                    // 3. 判断: 当前表单是否为文件上传表单            if (upload.isMultipartContent(request)){                // 4. 把请求数据转换为一个个FileItem对象,再用集合封装                List<FileItem> list = upload.parseRequest(request);                // 遍历: 得到每一个上传的数据                for (FileItem item: list){                    // 判断:普通文本数据                    if (item.isFormField()){                        // 普通文本数据                        String fieldName = item.getFieldName();    // 表单元素名称                        String content = item.getString();        // 表单元素名称, 对应的数据                        //item.getString("UTF-8");  指定编码                        System.out.println(fieldName + " " + content);                    }                    // 上传文件(文件流) ----> 上传到upload目录下                    else {                        // 普通文本数据                        String fieldName = item.getFieldName();    // 表单元素名称                        String name = item.getName();            // 文件名                                        String content = item.getString();        // 表单元素名称, 对应的数据                        String type = item.getContentType();    // 文件类型                        InputStream in = item.getInputStream(); // 上传文件流                                                /*                         *  四、文件名重名                         *  对于不同用户readme.txt文件,不希望覆盖!                         *  后台处理: 给用户添加一个唯一标记!                         */                        // a. 随机生成一个唯一标记                        String id = UUID.randomUUID().toString();                        // b. 与文件名拼接                        name = id +"#"+ name;                                                // 获取上传基路径                        String path = getServletContext().getRealPath("/upload");                        // 创建目标文件                        File file = new File(path,name);                                                // 工具类,文件上传                        item.write(file);                        item.delete();   //删除系统产生的临时文件                                                System.out.println();                    }                                    }                            }            else {                System.out.println("当前表单不是文件上传表单,处理失败!");            }        } catch (Exception e) {            e.printStackTrace();        }                }

 

文件案例:

index.jsp

<body>              <a href="${pageContext.request.contextPath }/upload.jsp">文件上传</a> &nbsp;&nbsp;&nbsp;          <a href="${pageContext.request.contextPath }/fileServlet?method=downList">文件下载</a>             </body>

 

Upload.jsp

<body>           <form name="frm_test" action="${pageContext.request.contextPath }/fileServlet?method=upload" method="post" enctype="multipart/form-data">            <%--<input type="hidden" name="method" value="upload">--%>                        用户名:<input type="text" name="userName">  <br/>           文件:   <input type="file" name="file_img">   <br/>                      <input type="submit" value="提交">        </form>  </body>

 

Downlist.jsp

<body>        <table border="1" align="center">        <tr>            <th>序号</th>            <th>文件名</th>            <th>操作</th>        </tr>        <c:forEach var="en" items="${requestScope.fileNames}" varStatus="vs">            <tr>                <td>${vs.count }</td>                <td>${en.value }</td>                <td>                    <%--<a href="${pageContext.request.contextPath }/fileServlet?method=down&..">下载</a>--%>                    <!-- 构建一个地址  -->                    <c:url var="url" value="fileServlet">                        <c:param name="method" value="down"></c:param>                        <c:param name="fileName" value="${en.key}"></c:param>                    </c:url>                    <!-- 使用上面地址 -->                    <a href="${url }">下载</a>                </td>            </tr>        </c:forEach>    </table>            </body>

 

FileServlet.java

/** * 处理文件上传与下载 * @author Jie.Yuan * */public class FileServlet extends HttpServlet {    public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        // 获取请求参数: 区分不同的操作类型        String method = request.getParameter("method");        if ("upload".equals(method)) {            // 上传            upload(request,response);        }                else if ("downList".equals(method)) {            // 进入下载列表            downList(request,response);        }                else if ("down".equals(method)) {            // 下载            down(request,response);        }    }            /**     * 1. 上传     */    private void upload(HttpServletRequest request, HttpServletResponse response)    throws ServletException, IOException {                try {            // 1. 创建工厂对象            FileItemFactory factory = new DiskFileItemFactory();            // 2. 文件上传核心工具类            ServletFileUpload upload = new ServletFileUpload(factory);            // 设置大小限制参数            upload.setFileSizeMax(10*1024*1024);    // 单个文件大小限制            upload.setSizeMax(50*1024*1024);        // 总文件大小限制            upload.setHeaderEncoding("UTF-8");        // 对中文文件编码处理            // 判断            if (upload.isMultipartContent(request)) {                // 3. 把请求数据转换为list集合                List<FileItem> list = upload.parseRequest(request);                // 遍历                for (FileItem item : list){                    // 判断:普通文本数据                    if (item.isFormField()){                        // 获取名称                        String name = item.getFieldName();                        // 获取值                        String value =http://www.mamicode.com/ item.getString();                        System.out.println(value);                    }                     // 文件表单项                    else {                        /******** 文件上传 ***********/                        // a. 获取文件名称                        String name = item.getName();                        // ----处理上传文件名重名问题----                        // a1. 先得到唯一标记                        String id = UUID.randomUUID().toString();                        // a2. 拼接文件名                        name = id + "#" + name;                                                                        // b. 得到上传目录                        String basePath = getServletContext().getRealPath("/upload");                        // c. 创建要上传的文件对象                        File file = new File(basePath,name);                        // d. 上传                        item.write(file);                        item.delete();  // 删除组件运行时产生的临时文件                    }                }            }        } catch (Exception e) {            e.printStackTrace();        }                        }        /**     * 2. 进入下载列表     */    private void downList(HttpServletRequest request, HttpServletResponse response)    throws ServletException, IOException {                // 实现思路:先获取upload目录下所有文件的文件名,再保存;跳转到down.jsp列表展示                //1. 初始化map集合Map<包含唯一标记的文件名, 简短文件名>  ;        Map<String,String> fileNames = new HashMap<String,String>();                //2. 获取上传目录,及其下所有的文件的文件名        String bathPath = getServletContext().getRealPath("/upload");        // 目录        File file = new File(bathPath);        // 目录下,所有文件名        String list[] = file.list();        // 遍历,封装        if (list != null && list.length > 0){            for (int i=0; i<list.length; i++){                // 全名                String fileName = list[i];                // 短名                String shortName = fileName.substring(fileName.lastIndexOf("#")+1);                // 封装                fileNames.put(fileName, shortName);            }        }                // 3. 保存到request域        request.setAttribute("fileNames", fileNames);        // 4. 转发        request.getRequestDispatcher("/downlist.jsp").forward(request, response);    }        /**     *  3. 处理下载     */    private void down(HttpServletRequest request, HttpServletResponse response)    throws ServletException, IOException {                // 获取用户下载的文件名称(url地址后追加数据,get)        String fileName = request.getParameter("fileName");        fileName = new String(fileName.getBytes("ISO8859-1"),"UTF-8");                // 先获取上传目录路径        String basePath = getServletContext().getRealPath("/upload");        // 获取一个文件流        InputStream in = new FileInputStream(new File(basePath,fileName));                // 如果文件名是中文,需要进行url编码        fileName = URLEncoder.encode(fileName, "UTF-8");        // 设置下载的响应头        response.setHeader("content-disposition", "attachment;fileName=" + fileName);                // 获取response字节流        OutputStream out = response.getOutputStream();        byte[] b = new byte[1024];        int len = -1;        while ((len = in.read(b)) != -1){            out.write(b, 0, len);        }        // 关闭        out.close();        in.close();                    }        public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        this.doGet(request, response);    }}

 

文件上传与下载