ztree+ajax实现文件树下载功能


Posted in Javascript onMay 18, 2021

基于java实现文件树下载,供大家参考,具体内容如下

0.项目准备工作

1.前端用到的插件库:

ztree官网

ztree+ajax实现文件树下载功能

2.后端maven依赖:

<dependencies>
  <!-- servlet依赖 -->
  <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
  </dependency>

  <!-- springMVC依赖 -->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.6.RELEASE</version>
  </dependency>

  <!-- 文件上传的jar包 -->
  <dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.8.0</version>
  </dependency>
  <dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.3</version>
  </dependency>
     // gson可以不要,这是我测试时使用的
    <dependency>
      <groupId>com.google.code.gson</groupId>
      <artifactId>gson</artifactId>
      <version>2.2.4</version>
    </dependency>

</dependencies>

3.web.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
  <!-- 声明springMvc的核心对象 DispatcherServlet -->
  <servlet>
    <servlet-name>web</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springConfig.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>web</servlet-name>
    <url-pattern>*.mvc</url-pattern>
  </servlet-mapping>

  <!--  注册字符集过滤器,解决post请求的中文乱码问题-->
  <filter>
    <filter-name>characterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>utf-8</param-value>
    </init-param>
    <init-param>
      <param-name>forRequestEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
    <init-param>
      <param-name>forResponseEncoding</param-name>
      <param-value>true</param-value>
    </init-param>

  </filter>
  <filter-mapping>
    <filter-name>characterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

4.springConfig.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!-- 开启组件扫描   -->
    <context:component-scan base-package="com.file"></context:component-scan>

    <!--声明 配置springMVC视图解析器-->
    <bean  class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--前缀:视图文件的路径-->
        <property name="prefix" value="/WEB-INF/view/" />
        <!--后缀:视图文件的扩展名-->
        <property name="suffix" value=".jsp" />
    </bean>

    <!--读写JSON的支持(Jackson)-->
    <mvc:annotation-driven />

    <!--  配置多媒体解析  -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!--  配置字符编码集 -->
        <property name="defaultEncoding" value="utf-8"> </property>
        <!-- 配置文件上传大小 单位是字节    -1代表没有限制 maxUploadSizePerFile是限制每个上传文件的大小,而maxUploadSize是限制总的上传文件大小  -->
        <property name="maxUploadSizePerFile" value="-1"> </property>

        <!-- ,不设置默认不限制总的上传文件大小,这里设置总的上传文件大小不超过1M(1*1024*1024) -->
        <property name="maxUploadSize" value="1048576"/>

    </bean>

</beans>

1.效果展示:

服务器端的文件目录:

ztree+ajax实现文件树下载功能

ztree+ajax实现文件树下载功能

ztree+ajax实现文件树下载功能

2.思路分析

1、需要递归遍历某个目录,并且判断是目录还是文件
2、找到父目录和子文件的关系,构建文件对象,将该对象加入到list集合中
3、将list集合转为json,返回给前端进行渲染
4、前端渲染出来的每个文件都包含一个该文件对应的下载url,点击该文件跳转到该文件的下载接口
5、提供下载接口,前端需要传递一个文件名称,然后后端根据文件名称去遍历指定的目录,查询是否有该文件,如果有,则将该文件进行下载

先来看下如果递归遍历获取到某个目录下的所有文件:

public class Test2 {
    
    public static void main(String[] args) {
        File file = new File("D:\\IDE2019");
        listFile(file);

    }

    public  static void listFile(File file ) {
        // 判断该文件是否存在
        if (file.exists()){
            // 获取当前文件夹下的所有子文件
            File[] files = file.listFiles();
            if (files!=null&&files.length>0){
                // 对该文件夹进行遍历
                for (int i = 0; i < files.length; i++) {
                    //  // 如果是一个目录继续进行递归
                    if (files[i].exists()&&files[i].isDirectory()){
                        listFile(files[i]);
                    }else {
                        // 不是目录,是一个文件,则输出文件名
                          System.out.println(files[i].getName());
                    }
                }
            }
        }

    }
    
}

3.前端实现代码:

代码:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">


  <link rel="stylesheet" href="../../css/zTreeStyle/zTreeStyle.css" rel="external nofollow" type="text/css">
  <script type="text/javascript" src="../../js/jquery-1.4.4.min.js"></script>
  <script type="text/javascript" src="../../js/jquery.ztree.core.min.js"></script>


  <title>文件下载</title>
</head>
<body>


<script>
  var settingss = {
    //zTree 的唯一标识,初始化后,等于 用户定义的 zTree 容器的 id 属性值。
    treeId:"treeDemo",
    data: {
      simpleData: {
        enable: true,  //true 、 false 分别表示 使用 、 不使用 简单数据模式
        idKey: "id",   //节点数据中保存唯一标识的属性名称
        pIdKey: "pId",    //节点数据中保存其父节点唯一标识的属性名称
        rootPId: "0"  //用于修正根节点父节点数据,即 pIdKey 指定的属性值
      },
      key: {
        name: "name"  //zTree 节点数据保存节点名称的属性名称  默认值:"name"
      }
    },
    check:{
      enable:true,  //true 、 false 分别表示 显示 、不显示 复选框或单选框
      nocheckInherit:false,   //当父节点设置 nocheck = true 时,设置子节点是否自动继承 nocheck = true
      chkboxType: { "Y": "p", "N": "s" }
    },

  };

  $(document).ready(function(){
    $.ajax({
      type:"get",
      url:"/file/init.mvc",
      async:true,
      success:function(result){

        console.log(result)
        // 得到ajax返回的数据 并且初始化文件树
       var zTreeObj = $.fn.zTree.init($("#treeDemo"), settingss, result); //初始化树
        zTreeObj.expandAll(false);   //true 节点全部展开、false节点收缩

      }
    });
  });


</script>
<div>
  <ul id="treeDemo" class="ztree"></ul>
</div>
</body>
</html>

4.后端代码实现:

1.抽象出来的实例对象bean

/**
 * @author compass
 * @version 1.0
 * @date 2021-05-14 22:41
 */
public class MyFile {

    private int id;
    private int pId;
    private String name;
    private String url;

    public MyFile(int id, int pId, String name, String url) {
        this.id = id;
        this.pId = pId;
        this.name = name;
        this.url = url;
    }

    @Override
    public String toString() {
        return "MyFile{" +
                "id=" + id +
                ", pId=" + pId +
                ", name='" + name + '\'' +
                ", url='" + url + '\'' +
                '}';
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getpId() {
        return pId;
    }

    public void setpId(int pId) {
        this.pId = pId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }
}

2.渲染数据和指定文件名查询文件地址的类

/**
 * @author compass
 * @version 1.0
 * @date 2021-05-15 12:31
 */
public class FilerService {

    // 将构建为文件对象的文件或目录放到list集合中
    List<MyFile> fileList = new ArrayList<>();

    /**
     * 功能:递归遍历文件,并且将文件或目录按照规定构建为对象 撞到List集合返回
     * @param file 待遍历的文件夹
     * @param index 扫描文件赋值指针 初始值为 :1
     * @return
     */
    public  List<MyFile> listAll1(File file , int index) {

        File[] listFiles=  file.listFiles();

        // 将文件或目录构建为对象
        for (int i=1;i<listFiles.length+1;i++){
            if (listFiles[i-1].isDirectory()){
                // 如果是目录 则url为空 pid=0说明是根目录
                MyFile myFile = new MyFile(i,0,listFiles[i-1].getName(),"");
                fileList.add(myFile);
            }else {
                // 如果是文件则拼接下载地址
                String filename=listFiles[i-1].getName();
                // 文件的id为:(目录id*100)+文件序列
                MyFile myFile = new MyFile((100*index)+i,index,listFiles[i-1].getName(),"http://localhost:8080/file/download.mvc?filename="+filename);
                fileList.add(myFile);
            }
        }
        // 判断该文件是否存在
        if (file.exists()){
            // 获取当前文件夹下的所有子文件
            File[] files = file.listFiles();
            if (files!=null&&files.length>0){
                // 对文件进行遍历
                for (int i = 0; i < files.length; i++) {
                    if (files[i].exists()&&files[i].isDirectory()){
                        // 如果是一个目录继续进行递归 直到找到文件为止 每遍历一个目录 index+1
                        listAll1(files[i],i+1);
                    }
                }
            }
        }
        return fileList;
    }

    // 制定文件的父目录
    String parentDir=null;

    /**
     * 根据传递过来的文件名 找到该文件的父文件夹,如果没有找到返回null
     * @param fileName 文件名
     * @param dir 需要查找的目录
     * @return
     */
    public  String getFileName(String fileName,File dir){
        if (dir.exists()){
             File[] files = dir.listFiles();
             if (files!=null&&files.length>0){
                for (int i=0;i<files.length;i++){
                    if (files[i].exists()&&files[i].isDirectory()){
                        getFileName(fileName,files[i]);
                    }else {
                        // 如果找到传递过来的文件名则赋值给 parentDir
                        if (fileName.equals(files[i].getName())){
                            parentDir=files[i].getParent();
                            break;
                        }
                    }
                }
             }
         }
        return parentDir;
    }
}

3.下载和渲染数据的Controller

/**
 * @author compass
 * @version 1.0
 * @date 2021-05-14 21:43
 */
@Controller
@RequestMapping("/file/")
public class FileDownloadController {


    // 提供访问接口
    @GetMapping("downloadIn.mvc")
    public String downloadIn(){
        return "index";
    }

    // 初始化页面数据
    @ResponseBody
    @GetMapping("init.mvc")
    public List<MyFile> test(){
        File file = new File("D:\\IDE2019\\work");
        FilerService service = new FilerService();
        // 将制定目录的文件夹 下的目录和文件构建为MyFile对象装到List集合中
        List<MyFile> listAll1 = service.listAll1(file, 1);
        // 返回Json数据给前端进行渲染
        return listAll1;
    }

    // 提供下载接口
    @GetMapping("download.mvc")
    public ResponseEntity <byte[]> fileDownload1(String filename,HttpServletRequest request) throws IOException {
        // 指定下载那个目录下的文件
        File file = new File("D:\\IDE2019\\work");
        FilerService service = new FilerService();
        // 获取到该文件的父目录
        String path = service.getFileName(filename, file);

        // 创建文件下载对象
        File downloadFile = new File(path, filename);

        HttpHeaders header = new HttpHeaders();
        header.setContentDispositionFormData("attachment",filename);
        header.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        ResponseEntity<byte[]> result = new ResponseEntity<>(FileUtils.readFileToByteArray(downloadFile), header, HttpStatus.OK);
        return result;
    }
}

测试:可以看到我们每点击一个文件都可以跳转到我们的下载接口,进行下载的。

ztree+ajax实现文件树下载功能

ztree+ajax实现文件树下载功能

这只是一个简单的使用,还有很多地方需要进行优化,当然也可以使用别的方法进行实现,这就是算是一个小练习吧,复习一下ajax和递归的知识。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
用prototype实现的简单小巧的多级联动菜单
Mar 24 Javascript
js 创建书签小工具之理论
Feb 25 Javascript
Javascript操作cookie的函数代码
Oct 03 Javascript
关于jQuery中.attr()和.prop()的问题探讨
Sep 06 Javascript
深入探讨JavaScript、JQuery屏蔽网页鼠标右键菜单及禁止选择复制
Jun 10 Javascript
一个JavaScript获取元素当前高度的实例
Oct 29 Javascript
Jquery 效果使用详解
Nov 23 Javascript
Node.js编写组件的三种实现方式
Feb 25 Javascript
详谈JS中实现种子随机数及作用
Jul 19 Javascript
React 子组件向父组件传值的方法
Jul 24 Javascript
解决echarts图表使用v-show控制图表显示不全的问题
Jul 19 Javascript
Node.js path模块,获取文件后缀名操作
Nov 07 Javascript
使用这 6个Vue加载动画库来减少我们网站的跳出率
一文带你理解vue创建一个后台管理系统流程(Vue+Element)
AJAX学习笔记
JS如何使用剪贴板操作Clipboard API
详解Node.js如何处理ES6模块
May 15 #Javascript
详解vue中v-for的key唯一性
解读Vue组件注册方式
May 15 #Vue.js
You might like
PHP Smarty生成EXCEL文档的代码
2008/08/23 PHP
php计算十二星座的函数代码
2012/08/21 PHP
PHP获取数组最大值下标的方法
2015/05/12 PHP
PHP 实现从数据库导出到.csv文件方法
2017/07/06 PHP
PHP设计模式之工厂模式实例总结
2017/09/01 PHP
数据结构之利用PHP实现二分搜索树
2020/10/25 PHP
js函数调用常用方法详解
2012/12/03 Javascript
JavaScript格式化日期时间的方法和自定义格式化函数示例
2014/04/04 Javascript
使用Node.js实现一个简单的FastCGI服务器实例
2014/06/09 Javascript
jQuery+css3动画属性制作猎豹浏览器宽屏banner焦点图
2015/03/16 Javascript
js正则匹配出所有图片及图片地址src的方法
2015/06/08 Javascript
基于Jquery+div+css实现弹出登录窗口(代码超简单)
2015/10/27 Javascript
一次$.getJSON不执行的简单记录
2016/07/19 Javascript
jQuery自定义图片上传插件实例代码
2017/04/04 jQuery
Angular2 组件间通过@Input @Output通讯示例
2017/08/24 Javascript
Vue项目pdf(base64)转图片遇到的问题及解决方法
2018/10/19 Javascript
Vue-cli3简单使用(图文步骤)
2019/04/30 Javascript
layui(1.0.9)文件上传upload,前后端的实例代码
2019/09/26 Javascript
JavaScript实现多文件下载方法解析
2020/08/07 Javascript
springboot+vue+对接支付宝接口+二维码扫描支付功能(沙箱环境)
2020/10/15 Javascript
Python设计模式之状态模式原理与用法详解
2019/01/15 Python
Python中按值来获取指定的键
2019/03/04 Python
python中pathlib模块的基本用法与总结
2020/08/17 Python
Django如何批量创建Model
2020/09/01 Python
python获取本周、上周、本月、上月及本季的时间代码实例
2020/09/08 Python
大型会议接待方案
2014/03/01 职场文书
护士自我鉴定总结
2014/03/24 职场文书
工商企业管理专业自荐信范文
2014/04/12 职场文书
授权委托书(完整版)
2014/09/10 职场文书
警察群众路线整改措施
2014/09/26 职场文书
小班下学期个人总结
2015/02/12 职场文书
学生乘坐校车安全责任书
2015/05/11 职场文书
Python爬虫:从m3u8文件里提取小视频的正确操作
2021/05/14 Python
Python爬虫之自动爬取某车之家各车销售数据
2021/06/02 Python
基于Pygame实现简单的贪吃蛇游戏
2021/12/06 Python
nginx 配置缓存
2022/05/11 Servers