ztree+ajax實(shí)現(xiàn)文件樹(shù)下載功能
基于java實(shí)現(xiàn)文件樹(shù)下載,供大家參考,具體內(nèi)容如下
0.項(xiàng)目準(zhǔn)備工作
1.前端用到的插件庫(kù):
ztree官網(wǎng)

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可以不要,這是我測(cè)試時(shí)使用的
<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的核心對(duì)象 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>
<!-- 注冊(cè)字符集過(guò)濾器,解決post請(qǐng)求的中文亂碼問(wèn)題-->
<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">
<!-- 開(kāi)啟組件掃描 -->
<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/" />
<!--后綴:視圖文件的擴(kuò)展名-->
<property name="suffix" value=".jsp" />
</bean>
<!--讀寫(xiě)JSON的支持(Jackson)-->
<mvc:annotation-driven />
<!-- 配置多媒體解析 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 配置字符編碼集 -->
<property name="defaultEncoding" value="utf-8"> </property>
<!-- 配置文件上傳大小 單位是字節(jié) -1代表沒(méi)有限制 maxUploadSizePerFile是限制每個(gè)上傳文件的大小,而maxUploadSize是限制總的上傳文件大小 -->
<property name="maxUploadSizePerFile" value="-1"> </property>
<!-- ,不設(shè)置默認(rèn)不限制總的上傳文件大小,這里設(shè)置總的上傳文件大小不超過(guò)1M(1*1024*1024) -->
<property name="maxUploadSize" value="1048576"/>
</bean>
</beans>
1.效果展示:
服務(wù)器端的文件目錄:



2.思路分析
1、需要遞歸遍歷某個(gè)目錄,并且判斷是目錄還是文件
2、找到父目錄和子文件的關(guān)系,構(gòu)建文件對(duì)象,將該對(duì)象加入到list集合中
3、將list集合轉(zhuǎn)為json,返回給前端進(jìn)行渲染
4、前端渲染出來(lái)的每個(gè)文件都包含一個(gè)該文件對(duì)應(yīng)的下載url,點(diǎn)擊該文件跳轉(zhuǎn)到該文件的下載接口
5、提供下載接口,前端需要傳遞一個(gè)文件名稱,然后后端根據(jù)文件名稱去遍歷指定的目錄,查詢是否有該文件,如果有,則將該文件進(jìn)行下載
先來(lái)看下如果遞歸遍歷獲取到某個(gè)目錄下的所有文件:
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()){
// 獲取當(dāng)前文件夾下的所有子文件
File[] files = file.listFiles();
if (files!=null&&files.length>0){
// 對(duì)該文件夾進(jìn)行遍歷
for (int i = 0; i < files.length; i++) {
// // 如果是一個(gè)目錄繼續(xù)進(jìn)行遞歸
if (files[i].exists()&&files[i].isDirectory()){
listFile(files[i]);
}else {
// 不是目錄,是一個(gè)文件,則輸出文件名
System.out.println(files[i].getName());
}
}
}
}
}
}
3.前端實(shí)現(xiàn)代碼:
代碼:
<%@ 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 的唯一標(biāo)識(shí),初始化后,等于 用戶定義的 zTree 容器的 id 屬性值。
treeId:"treeDemo",
data: {
simpleData: {
enable: true, //true 、 false 分別表示 使用 、 不使用 簡(jiǎn)單數(shù)據(jù)模式
idKey: "id", //節(jié)點(diǎn)數(shù)據(jù)中保存唯一標(biāo)識(shí)的屬性名稱
pIdKey: "pId", //節(jié)點(diǎn)數(shù)據(jù)中保存其父節(jié)點(diǎn)唯一標(biāo)識(shí)的屬性名稱
rootPId: "0" //用于修正根節(jié)點(diǎn)父節(jié)點(diǎn)數(shù)據(jù),即 pIdKey 指定的屬性值
},
key: {
name: "name" //zTree 節(jié)點(diǎn)數(shù)據(jù)保存節(jié)點(diǎn)名稱的屬性名稱 默認(rèn)值:"name"
}
},
check:{
enable:true, //true 、 false 分別表示 顯示 、不顯示 復(fù)選框或單選框
nocheckInherit:false, //當(dāng)父節(jié)點(diǎn)設(shè)置 nocheck = true 時(shí),設(shè)置子節(jié)點(diǎn)是否自動(dòng)繼承 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返回的數(shù)據(jù) 并且初始化文件樹(shù)
var zTreeObj = $.fn.zTree.init($("#treeDemo"), settingss, result); //初始化樹(shù)
zTreeObj.expandAll(false); //true 節(jié)點(diǎn)全部展開(kāi)、false節(jié)點(diǎn)收縮
}
});
});
</script>
<div>
<ul id="treeDemo" class="ztree"></ul>
</div>
</body>
</html>
4.后端代碼實(shí)現(xiàn):
1.抽象出來(lái)的實(shí)例對(duì)象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.渲染數(shù)據(jù)和指定文件名查詢文件地址的類
/**
* @author compass
* @version 1.0
* @date 2021-05-15 12:31
*/
public class FilerService {
// 將構(gòu)建為文件對(duì)象的文件或目錄放到list集合中
List<MyFile> fileList = new ArrayList<>();
/**
* 功能:遞歸遍歷文件,并且將文件或目錄按照規(guī)定構(gòu)建為對(duì)象 撞到List集合返回
* @param file 待遍歷的文件夾
* @param index 掃描文件賦值指針 初始值為 :1
* @return
*/
public List<MyFile> listAll1(File file , int index) {
File[] listFiles= file.listFiles();
// 將文件或目錄構(gòu)建為對(duì)象
for (int i=1;i<listFiles.length+1;i++){
if (listFiles[i-1].isDirectory()){
// 如果是目錄 則url為空 pid=0說(shuō)明是根目錄
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()){
// 獲取當(dāng)前文件夾下的所有子文件
File[] files = file.listFiles();
if (files!=null&&files.length>0){
// 對(duì)文件進(jìn)行遍歷
for (int i = 0; i < files.length; i++) {
if (files[i].exists()&&files[i].isDirectory()){
// 如果是一個(gè)目錄繼續(xù)進(jìn)行遞歸 直到找到文件為止 每遍歷一個(gè)目錄 index+1
listAll1(files[i],i+1);
}
}
}
}
return fileList;
}
// 制定文件的父目錄
String parentDir=null;
/**
* 根據(jù)傳遞過(guò)來(lái)的文件名 找到該文件的父文件夾,如果沒(méi)有找到返回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 {
// 如果找到傳遞過(guò)來(lái)的文件名則賦值給 parentDir
if (fileName.equals(files[i].getName())){
parentDir=files[i].getParent();
break;
}
}
}
}
}
return parentDir;
}
}
3.下載和渲染數(shù)據(jù)的Controller
/**
* @author compass
* @version 1.0
* @date 2021-05-14 21:43
*/
@Controller
@RequestMapping("/file/")
public class FileDownloadController {
// 提供訪問(wèn)接口
@GetMapping("downloadIn.mvc")
public String downloadIn(){
return "index";
}
// 初始化頁(yè)面數(shù)據(jù)
@ResponseBody
@GetMapping("init.mvc")
public List<MyFile> test(){
File file = new File("D:\\IDE2019\\work");
FilerService service = new FilerService();
// 將制定目錄的文件夾 下的目錄和文件構(gòu)建為MyFile對(duì)象裝到List集合中
List<MyFile> listAll1 = service.listAll1(file, 1);
// 返回Json數(shù)據(jù)給前端進(jìn)行渲染
return listAll1;
}
// 提供下載接口
@GetMapping("download.mvc")
public ResponseEntity <byte[]> fileDownload1(String filename,HttpServletRequest request) throws IOException {
// 指定下載那個(gè)目錄下的文件
File file = new File("D:\\IDE2019\\work");
FilerService service = new FilerService();
// 獲取到該文件的父目錄
String path = service.getFileName(filename, file);
// 創(chuàng)建文件下載對(duì)象
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;
}
}
測(cè)試:可以看到我們每點(diǎn)擊一個(gè)文件都可以跳轉(zhuǎn)到我們的下載接口,進(jìn)行下載的。


這只是一個(gè)簡(jiǎn)單的使用,還有很多地方需要進(jìn)行優(yōu)化,當(dāng)然也可以使用別的方法進(jìn)行實(shí)現(xiàn),這就是算是一個(gè)小練習(xí)吧,復(fù)習(xí)一下ajax和遞歸的知識(shí)。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- JQuery的AJAX實(shí)現(xiàn)文件下載的小例子
- Ajax請(qǐng)求二進(jìn)制流進(jìn)行處理(ajax異步下載文件)的簡(jiǎn)單方法
- Ajax實(shí)現(xiàn)文件下載
- Jquery Ajax請(qǐng)求文件下載操作失敗的原因分析及解決辦法
- Ajax 生成流文件下載(實(shí)現(xiàn)代碼)
- jQuery的ajax下載blob文件
- 使用Ajax生成的Excel文件并下載的實(shí)例
- jQuery使用動(dòng)態(tài)渲染表單功能完成ajax文件下載
- SpringMVC+Ajax實(shí)現(xiàn)文件批量上傳和下載功能實(shí)例代碼
- PHP使用ajax的post方式下載excel文件簡(jiǎn)單示例
相關(guān)文章
Ajax實(shí)現(xiàn)跨域訪問(wèn)的三種方法
本文給大家介紹了ajax實(shí)現(xiàn)跨域訪問(wèn)的3種解決方案,非常的實(shí)用,個(gè)人比較推薦第三種,小伙伴們可以著重看下。2015-06-06
ASP.NET與Ajax的實(shí)現(xiàn)方式小總結(jié)
Ajax 應(yīng)該不是一項(xiàng)技術(shù),是一種思想而已,跟 ASP.NET 以及其它 Web 開(kāi)發(fā)語(yǔ)言沒(méi)有什么太大關(guān)系,這里只是談?wù)?ASP.NET 中目前使用的 Ajax 技術(shù)以及其它一些實(shí)現(xiàn) Ajax 的優(yōu)秀框架。感興趣的朋友跟著小編一起學(xué)習(xí)asp.net與ajax的實(shí)現(xiàn)方式2015-09-09
ajax動(dòng)態(tài)賦值echarts的實(shí)例(餅圖和柱形圖)
下面小編就為大家分享一篇ajax動(dòng)態(tài)賦值echarts的實(shí)例(餅圖和柱形圖),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-03-03
用AJAX實(shí)現(xiàn)的無(wú)刷新的分頁(yè)實(shí)現(xiàn)代碼(asp.net)
最近學(xué)習(xí)了AJAX技術(shù)。AJAX,指的是異步的Javascript和xml。它的基本原理就是頁(yè)面用Javascript發(fā)送一個(gè)異步的http請(qǐng)求到服務(wù)器,服務(wù)器返回?cái)?shù)據(jù)后,再用Javascript靜態(tài)的去更改頁(yè)面某個(gè)地方的值,而無(wú)需提交表單。2011-04-04
Ajax實(shí)現(xiàn)異步用戶名驗(yàn)證功能
當(dāng)用戶填寫(xiě)好賬號(hào)切換到密碼框的時(shí)候,使用ajax驗(yàn)證賬號(hào)的可用性。這篇文章就主要為大家詳細(xì)介紹了Ajax實(shí)現(xiàn)異步用戶名驗(yàn)證功能,感興趣的小伙伴們可以參考一下2016-05-05
有關(guān)Ajax中g(shù)et和post的使用問(wèn)題
下面小編就為大家?guī)?lái)一篇有關(guān)Ajax中g(shù)et和post的使用問(wèn)題。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-06-06
一個(gè)簡(jiǎn)單的ASP+AJAX留言本源碼下載
一個(gè)簡(jiǎn)單的ASP+AJAX留言本源碼下載...2007-06-06
分享Ajax創(chuàng)建簡(jiǎn)單實(shí)例代碼
這篇文章主要為大家分享了Ajax創(chuàng)建簡(jiǎn)單實(shí)例代碼,學(xué)習(xí)Ajax如何創(chuàng)建簡(jiǎn)單實(shí)例,感興趣的小伙伴們可以參考一下2015-12-12

