ztree+ajax实现文件树下载功能
基于java实现文件树下载,供大家参考,具体内容如下
0.项目准备工作
1.前端用到的插件库:
ztree官网
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.效果展示:
服务器端的文件目录:
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; } }
测试:可以看到我们每点击一个文件都可以跳转到我们的下载接口,进行下载的。
这只是一个简单的使用,还有很多地方需要进行优化,当然也可以使用别的方法进行实现,这就是算是一个小练习吧,复习一下ajax和递归的知识。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持硕编程。