0%

JavaWeb文件上传下载,使用fileupload组件

处理下载文件名乱码问题,包括某些情况下chrome出现的乱码。

一、引入jar包

  1. commons-fileupload-1.2.1.jar

  2. commons-io-1.4.jar

二、文件上传

  1. html代码

    1
    2
    3
    4
    5
    <form name="upload_test" action="${pageContext.request.contextPath}/FileServlet?method=upload" method="post" enctype="multipart/form-data">
    用户名: <input type="text" name="userName" > <br>
    文件: <input type="file" name="fileName" > <br>
    <input type="submit" value="上传" >
    </form>
  2. java代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    private void upload(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    String uri = null;
    try {
    //文件上传工厂
    FileItemFactory factory = new DiskFileItemFactory();
    //文件上传核心工具类
    ServletFileUpload upload = new ServletFileUpload(factory);
    /******设置大小限制参数******/
    // 单个文件大小限制
    upload.setFileSizeMax(10*1024*1024);
    // 总文件大小限制
    upload.setSizeMax(50*1024*1024);
    // 对中文文件编码处理
    upload.setHeaderEncoding("UTF-8");
    //判断: 当前表单是否为文件上传表单
    if(upload.isMultipartContent(request)){
    //把请求数据转换为一个FileItem对象,再用集合封装
    List<FileItem> list = upload.parseRequest(request);
    // 遍历: 得到每一个上传的数据
    for (FileItem item : list) {
    // 判断类型(true:普通表单 || false:上传表单)
    if(item.isFormField()){
    //获取名称
    String name = item.getFieldName();
    //获取值
    String value = item.getString();
    //打印内容
    System.out.println("name: " + name + "\tvalue: " + value);
    } else {
    /*****上传表单*****/
    //获取文件名称
    String name = item.getName();
    // ----处理上传文件名重名问题----
    //获取一个36位的uuid字符串
    String id = UUID.randomUUID().toString();
    //拼接文件名
    name = id + "#" + name;
    //得到上传目录
    String basePath = getServletContext().getRealPath("upload");
    System.out.println("basePath: " + basePath);
    //创建要上传的文件对象
    File file = new File(basePath, name);
    //上传
    item.write(file);
    // 删除组件运行时产生的临时文件
    item.delete();
    }
    }
    } else {
    System.out.println("不是上传表单");
    }

    uri = "/success.jsp";
    } catch (FileUploadException e) {
    e.printStackTrace();
    uri = "/error/error.jsp";
    } catch (Exception e) {
    e.printStackTrace();
    uri = "/error/error.jsp";
    } finally {
    request.getRequestDispatcher(uri).forward(request, response);
    }
    }

三、文件列表

  1. html代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    <table border="1" width="80%" align="center" cellpadding="5" cellspacing="0">
    <tr>
    <th>序号</th>
    <th>文件名</th>
    <th>操作</th>
    </tr>
    <c:choose>
    <c:when test="${not empty requestScope.fileMap}">
    <c:forEach items="${requestScope.fileMap }" var="en" varStatus="vs">
    <tr>
    <td>${vs.count }</td>
    <td>${en.value }</td>
    <td>
    <!-- 构建一个地址 -->
    <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>
    </c:when>
    <c:otherwise>
    <tr>
    <td align="center" colspan="3">对不起,没有你要找的数据</td>
    </tr>
    </c:otherwise>
    </c:choose>
    </table>
  2. java代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    private void downList(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    // 实现思路:先获取upload目录下所有文件的文件名,再保存;跳转到down.jsp列表展示

    //初始化map集合Map<包含唯一标记的文件名, 简短文件名>
    Map<String, String> fileMap = new HashMap<String, String>();
    //获取上传目录
    String basePath = getServletContext().getRealPath("/upload");
    System.out.println(basePath);
    //目录
    File file = new File(basePath);
    //遍历目录获取文件名
    String[] list = file.list();
    //遍历,封装
    if (list != null && list.length > 0) {
    for (String name : list) {
    System.out.println(name);
    String shortName = name.substring(name.lastIndexOf("#")+1);
    System.out.println("shortName: " + shortName);
    fileMap.put(name, shortName);
    }
    }

    //保存到request域
    request.setAttribute("fileMap", fileMap);
    //转发
    request.getRequestDispatcher("/downlist.jsp").forward(request, response);

    }

三、文件下载

  1. java代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    private void down(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    // 获取用户下载的文件名称(url地址后追加数据,get)
    String fileName = request.getParameter("fileName");
    System.out.println("未编码:" + fileName);

    //获取文件目录路径
    String basePath = getServletContext().getRealPath("/upload");
    //获取文件流
    InputStream is = new FileInputStream(new File(basePath, fileName));

    //截取字符串
    String shortName = fileName.substring(fileName.lastIndexOf("#")+1);
    System.out.println("截取后未编码:" + shortName);
    shortName = new String(shortName.getBytes(),"ISO8859-1");
    System.out.println("截取后编码:" + shortName);

    //设置浏览器编码
    response.setCharacterEncoding("UTF-8");
    // 设置下载的响应头
    response.addHeader("content-disposition", "attachment;fileName="+shortName);
    // 获取response字节流
    OutputStream os = response.getOutputStream();
    byte[] by = new byte[1024];
    int len = -1;
    while ((len = is.read(by)) != -1) {
    os.write(by, 0, len);
    }

    //关闭
    os.close();
    is.close();

    }