文章标题

浏览器在上传的过程中是将文件以流的形式提交到服务器端,一般选择采用apache的开源工具common-fileupload这个文件上传组件,common-fileupload依赖于common-io包,因此开发工程中需要导入common-fileupload ,和 common-io 包。
在保存文件名的,可能存在文件重名覆盖问题,处理这类问题方式很多, 如为每个上传文件创建一个独立文件夹,再保存文件, 将文件名加UUID保存文件。 为了方便在服务器查找文件,本文将采用修改文件名方式保存文件。 服务器存储文件名格式: 原文件名 + “_” + UUID + 文件扩展名(如:IMG20140405_ef039b09-ef4d-405e-86b5-bd59604c014e.jpg)。 考虑文件安全性,将上传文件保存在WEB-INF\upload目录, 临时目录 WEB-INF/temp 。

1 添加前台文件upLoad.jsp
[html] view plain copy 在CODE上查看代码片派生到我的代码片
<%@ page language=”java” import=”java.util.*” pageEncoding=”UTF-8”%>




文件上传








上传用户:

上传文件1:

上传文件2:




注意: 表单提交方式需设置为post提交,设置ebctype属性值为multipart/form-data

2 添加后台处理servlet文件UploadHandleServlet.java
设置url访问路径为/UploadHandleServlet
[java] view plain copy 在CODE上查看代码片派生到我的代码片
package cjr.servlet;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
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.FileUploadBase;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

public class UploadHandleServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)  
        throws ServletException, IOException {  
    doPost(request, response);  
}  
public void doPost(HttpServletRequest request, HttpServletResponse response)  
        throws ServletException, IOException {  
    // 得到上传文件的保存目录,将上传的文件存放于WEB-INF目录下,不允许外界直接访问,保证上传文件的安全  
    String savePath = this.getServletContext().getRealPath(  
            "/WEB-INF/upload");  
    // 上传时生成的临时文件保存目录  
    String tempPath = this.getServletContext().getRealPath("/WEB-INF/temp");  
    File tmpFile = new File(tempPath);  
    if (!tmpFile.exists()) {  
        // 创建临时目录  
        tmpFile.mkdir();  
    }  
    // 消息提示  
    String message = "上传成功";  
    try {  
        // 使用Apache文件上传组件处理文件上传步骤:  
        // 1、创建一个DiskFileItemFactory工厂  
        DiskFileItemFactory factory = new DiskFileItemFactory();  
        // 设置工厂的缓冲区的大小,当上传的文件大小超过缓冲区的大小时,就会生成一个临时文件存放到指定的临时目录当中。  
        factory.setSizeThreshold(1024 * 100);// 设置缓冲区的大小为100KB,如果不指定,那么缓冲区的大小默认是10KB  
        // 设置上传时生成的临时文件的保存目录  
        factory.setRepository(tmpFile);  
        // 2、创建一个文件上传解析器  
        ServletFileUpload upload = new ServletFileUpload(factory);  
        // 监听文件上传进度  
        upload.setProgressListener(new ProgressListener() {  
            public void update(long pBytesRead, long pContentLength,  
                    int arg2) {  
                System.out.println("文件大小为:" + pContentLength + ",当前已处理:"  
                        + pBytesRead);  
                /** 
                 * 文件大小为:14608,当前已处理:4096 文件大小为:14608,当前已处理:7367 
                 * 文件大小为:14608,当前已处理:11419 文件大小为:14608,当前已处理:14608 
                 */  
            }  
        });  
        // 解决上传文件名的中文乱码  
        upload.setHeaderEncoding("UTF-8");  
        // 3、判断提交上来的数据是否是上传表单的数据  
        if (!ServletFileUpload.isMultipartContent(request)) {  
            // 按照传统方式获取数据  
            return;  
        }  
        // 设置上传单个文件的大小的最大值,目前是设置为1024*1024*3字节,也就是3MB  
        upload.setFileSizeMax(1024 * 1024 * 3);  
        // 设置上传文件总量的最大值,最大值=同时上传的多个文件的大小的最大值的和,目前设置为20MB  
        upload.setSizeMax(1024 * 1024 * 20);  
        // 4、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List<FileItem>集合,每一个FileItem对应一个Form表单的输入项  
        @SuppressWarnings("unchecked")  
        List<FileItem> list = upload.parseRequest(request);  
        for (FileItem item : list) {  
            // 如果fileitem中封装的是普通输入项的数据  
            if (item.isFormField()) {  
                String name = item.getFieldName();  
                // 解决普通输入项的数据的中文乱码问题  
                String value = item.getString("UTF-8");  
                // value = new String(value.getBytes("iso8859-1"),"UTF-8");  
                System.out.println(name + "=" + value);  
            } else {// 如果fileitem中封装的是上传文件  
                // 得到上传的文件名称,  
                String filename = item.getName();  
                System.out.println(filename);  
                if (filename == null || filename.trim().equals("")) {  
                    continue;  
                }  
                // 注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名是带有路径的,如:  
                // c:\a\b\1.txt,而有些只是单纯的文件名,如:1.txt  
                // 处理获取到的上传文件的文件名的路径部分,只保留文件名部分  
                filename = filename  
                        .substring(filename.lastIndexOf("\\") + 1);  
                // 获取item中的上传文件的输入流  
                InputStream in = item.getInputStream();  
                // 创建一个文件输出流  
                FileOutputStream out = new FileOutputStream(savePath + "\\" + makeFileName(filename));  
                // 创建一个缓冲区  
                byte buffer[] = new byte[1024];  
                // 判断输入流中的数据是否已经读完的标识   
                int len = 0;  
                // 循环将输入流读入到缓冲区当中,(len=in.read(buffer))>0就表示in里面还有数据  
                while ((len = in.read(buffer)) > 0) {  
                    // 使用FileOutputStream输出流将缓冲区的数据写入到指定的目录(savePath + "\\"  
                    // + makeFileName(filename))当中  
                    out.write(buffer, 0, len);  
                }  
                // 关闭输入流  
                in.close();  
                // 关闭输出流  
                out.close();   
                // 删除处理文件上传时生成的临时文件   
                item.delete();   
            }  
        }  
    } catch (FileUploadBase.FileSizeLimitExceededException e) {  
        e.printStackTrace();  
        request.setAttribute("message", "单个文件超出最大值!!!");  
        request.getRequestDispatcher("/message.jsp").forward(request,  
                response);  
        return;  
    } catch (FileUploadBase.SizeLimitExceededException e) {  
        e.printStackTrace();  
        request.setAttribute("message", "上传文件的总的大小超出限制的最大值!!!");  
        request.getRequestDispatcher("/message.jsp").forward(request,  
                response);  
        return;  
    } catch (Exception e) {  
        message = "文件上传失败!";  
        e.printStackTrace();  
    }  
    request.setAttribute("message", message);  
    request.getRequestDispatcher("/message.jsp").forward(request, response);  
}  

private String makeFileName(String filename) { // 2.jpg  
    // 为防止文件覆盖的现象发生,要为上传文件产生一个唯一的文件名  
    int index = filename.lastIndexOf(".");  
    String fileAName = filename.substring(0,index) + "_"   
    +  UUID.randomUUID().toString() + filename.substring(index);  
    return fileAName;  
}  

}

3 添加前台结果显示文件 message.jsp
[html] view plain copy 在CODE上查看代码片派生到我的代码片
<%@ page language=”java” import=”java.util.*” pageEncoding=”UTF-8”%>




上传结果






结果记录: ${message}

4 显示文件列表
4.1 添加servlet处理文件ListFileServlet.java,url访问路径为/ListFileServlet。循环显示遍历WEB-INFO\upload 文件夹下的文件。
[java] view plain copy 在CODE上查看代码片派生到我的代码片
package cjr.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 ListFileServlet extends HttpServlet {

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

public void doPost(HttpServletRequest request, HttpServletResponse response)  
        throws ServletException, IOException {  
    // 获取上传文件的目录  
    String uploadFilePath = this.getServletContext().getRealPath(  
            "/WEB-INF/upload");  
    // 存储要下载的文件名  
    Map<String, String> fileNameMap = new HashMap<String, String>();  
    // 递归遍历filepath目录下的所有文件和目录,将文件的文件名存储到map集合中  
    listfile(new File(uploadFilePath), fileNameMap);// File既可以代表一个文件也可以代表一个目录  
    // 将Map集合发送到listfile.jsp页面进行显示  
    request.setAttribute("fileNameMap", fileNameMap);  
    request.getRequestDispatcher("/listfile.jsp")  
            .forward(request, response);  
}  

public void listfile(File file, Map<String, String> map) {  
    // 如果file代表的不是一个文件,而是一个目录  
    if (!file.isFile()) {  
        // 列出该目录下的所有文件和目录  
        File[] files = file.listFiles();  
        // 遍历files[]数组  
        for (File f : files) {  
            // 递归  
            listfile(f, map);  
        }  
    } else {  
        String fileOrgName = file.getName();  
        int index1 = fileOrgName.lastIndexOf("_");  
        int index2 = fileOrgName.lastIndexOf(".");  
        String fileName = fileOrgName.substring(0, index1) + fileOrgName.substring(index2);  
        map.put(file.getName(), fileName);  
    }  
}  

}

4.2 添加显示界面 listfile.jsp
[html] view plain copy 在CODE上查看代码片派生到我的代码片
<%@ page language=”java” import=”java.util.*” pageEncoding=”UTF-8”%>
<%@ taglib prefix=”c” uri=”http://java.sun.com/jsp/jstl/core” %>



文件列表











me.value<ahref=" {downurl}”>下载




5 文件下载
添加文件DownLoadServlet.java,设置访问访问url:/DownLoadServlet
[java] view plain copy 在CODE上查看代码片派生到我的代码片
package cjr.servlet;

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

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

public class DownLoadServlet extends HttpServlet {

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

public void doPost(HttpServletRequest request, HttpServletResponse response)  
        throws ServletException, IOException {  
    // 得到要下载的文件名  
    String fileName = request.getParameter("filename"); // 23239283-92489-阿凡达.avi  
    fileName = new String(fileName.getBytes("iso8859-1"), "UTF-8");  
    // 上传的文件都是保存在/WEB-INF/upload目录下的子目录当中  
    String fileSaveRootPath = this.getServletContext().getRealPath(  
            "/WEB-INF/upload");  
    // 得到要下载的文件  
    File file = new File(fileSaveRootPath + "\\" + fileName);  
    // 如果文件不存在  
    if (!file.exists()) {  
        request.setAttribute("message", "您要下载的资源已被删除!!");  
        request.getRequestDispatcher("/message.jsp").forward(request,  
                response);  
        return;  
    }  
    // 处理文件名  
    int index1 = fileName.lastIndexOf("_");  
    int index2 = fileName.lastIndexOf(".");  
    String realname = fileName.substring(0, index1) + fileName.substring(index2);  
    // 设置响应头,控制浏览器下载该文件  
    response.setHeader("content-disposition", "attachment;filename="  
            + URLEncoder.encode(realname, "UTF-8"));  
    // 读取要下载的文件,保存到文件输入流  
    FileInputStream in = new FileInputStream(fileSaveRootPath + "\\" + fileName);  
    // 创建输出流  
    OutputStream out = response.getOutputStream();  
    // 创建缓冲区  
    byte buffer[] = new byte[1024];  
    int len = 0;  
    // 循环将输入流中的内容读取到缓冲区当中  
    while ((len = in.read(buffer)) > 0) {  
        // 输出缓冲区的内容到浏览器,实现文件下载  
        out.write(buffer, 0, len);  
    }  
    // 关闭文件输入流  
    in.close();  
    // 关闭输出流  
    out.close();  
}  

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值