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 相关文章推荐
JS实现的省份级联实例代码
Jun 24 Javascript
javascript中的作用域和上下文使用简要概述
Dec 05 Javascript
js与运算符和或运算符的妙用
Feb 14 Javascript
js实现分享到随页面滚动而滑动效果的方法
Apr 10 Javascript
JavaScript中解析JSON数据的三种方法
Jul 03 Javascript
jQuery Ajax 全局调用封装实例代码详解
Jun 02 Javascript
JavaScript实现经典排序算法之冒泡排序
Dec 28 Javascript
JS实现元素上下左右移动效果
Oct 18 Javascript
详解使用vuex进行菜单管理
Dec 21 Javascript
Vue源码解析之数组变异的实现
Dec 04 Javascript
Vue.js暴露方法给WebView的使用操作
Sep 07 Javascript
微信小程序实现简单购物车功能
Dec 30 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
利用static实现表格的颜色隔行显示
2006/10/09 PHP
PHP中uploaded_files函数使用方法详解
2011/03/09 PHP
php基于Fleaphp框架实现cvs数据导入MySQL的方法
2016/02/23 PHP
关于JavaScript的with 语句的使用方法
2011/05/09 Javascript
在Javascript里访问SharePoint列表数据的实现方法
2011/05/22 Javascript
在JavaScript中监听IME键盘输入事件
2011/05/29 Javascript
js打造数组转json函数
2015/01/14 Javascript
JavaScript程序开发之JS代码放置的位置
2016/01/15 Javascript
Javascript之BOM(window对象)详解
2016/05/25 Javascript
让浏览器崩溃的12行JS代码(DoS攻击分析及防御)
2016/10/10 Javascript
获取url中用&amp;隔开的参数实例(分享)
2017/05/28 Javascript
微信小程序生成分享海报方法(附带二维码生成)
2019/03/29 Javascript
Vue起步(无cli)的啊教程详解
2019/04/11 Javascript
浅谈vue 锚点指令v-anchor的使用
2019/11/13 Javascript
JS中间件设计模式的深入探讨与实例分析
2020/04/11 Javascript
vue打开其他项目页面并传入数据详解
2020/11/25 Vue.js
[03:49]辉夜杯现场龙骑士COSER秀情商“我喜欢芬队!”
2015/12/27 DOTA
Python 探针的实现原理
2016/04/23 Python
微信跳一跳自动运行python脚本
2018/01/08 Python
python中实现将多个print输出合成一个数组
2018/04/19 Python
Python Cookie 读取和保存方法
2018/12/28 Python
python使用参数对嵌套字典进行取值的方法
2019/04/26 Python
python图像和办公文档处理总结
2019/05/28 Python
pytorch 批次遍历数据集打印数据的例子
2019/12/30 Python
python logging.basicConfig不生效的原因及解决
2020/02/20 Python
美国滑雪和滑雪板商店:Buckman
2018/03/03 全球购物
如何反序的迭代一个序列?how do I iterate over a sequence in reverse order
2012/02/04 面试题
教师师德教育的自我评价
2013/10/31 职场文书
老师的检讨书
2014/02/23 职场文书
核心价值观演讲稿
2014/05/13 职场文书
公司优秀员工获奖感言
2014/08/14 职场文书
党的群众路线对照检查材料(个人)
2014/09/24 职场文书
创业者如何撰写出一份打动投资人的商业计划书?
2019/07/02 职场文书
导游词之太原天龙山
2020/01/02 职场文书
Python OpenCV实现传统图片格式与base64转换
2021/06/13 Python
Java用自带的Image IO给图片添加水印
2021/06/15 Java/Android