SpringMVC框架下實現文檔上傳和文檔下載總結

文件上傳的思路:

       我們需要先上傳文件,將文件信息進行上傳,然後通過io保存起來,保存在服務器上的某個位置,然後將保存的文件名返回回來,然後將文件名保存到一個hidden類型的輸入框中,當你填寫好積分的時候點擊提交按鈕一併上傳上去,保存到數據庫。

       簡而言之,文件上傳就兩步:

       1.點擊選擇文件按鈕,把文件提交到服務器的某個位置,然後把返回的文件名和文件類型渲染到界面上,但是是通過input框的類型爲hidden隱藏起來

       2.點擊上傳文件按鈕,把文件名,文件類型,文檔簡介,下載積分這四項插入到數據庫中。

文件下載的思路:

       文件下載都是需要跟着參數,一般我們跟着的是文件的id,通過id去數據庫查找文件名,找到對應的路徑,然後下載下來。 

 

如果你理解了文件上傳和下載的思路,你就會發現做起來並沒有那麼難,還會覺得有點簡單。

 

1.文件上傳具體步驟:

1.1.首先看一下上傳文件界面是什麼樣

1.2.界面代碼:我用到了前端框架zui,所以我引入了zui的包

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>上傳文件界面</title>
<link rel="stylesheet" href="dist/css/zui.min.css">
<link href="dist/lib/uploader/zui.uploader.min.css" rel="stylesheet">
</head>
<body>
	<div class="panel" style="width: 450px;height:auto; margin: 150px auto;">
		<div class="panel-heading">文件上傳</div>
		<div class="panel-body">
			<div id="uploaderExample" class="uploader">
				<div class="file-list" data-drag-placeholder="請拖拽文件到此處"></div>
				<button type="button" class="btn btn-primary uploader-btn-browse">
					<i class="icon icon-cloud-upload"></i> 選擇文件
				</button>
			</div>
			<div class="col-xs-12"> 
                            <span class="input-group-addon">文檔簡介</span>
                            <textarea name="fileIntro" id="fileIntro" cols="30" rows="10" class="form-control"></textarea>
                    </div>

                        <div class="input-group with-padding">
                            <span class="input-group-addon">下載積分</span>
                           <input type="text" name="fileScore" id="fileScore" class="form-control" placeholder="請輸入下載積分">
                        </div>
                     
             <div class="col-xs-12"> 
                       
			<a class="btn btn-block" οnclick="upAll()">上傳文件</a>
         </div>
         <div id="fileContent"></div>
		</div>
	</div>
</body>
<script src="dist/lib/jquery/jquery.js"></script>
<script src="dist/js/zui.min.js"></script>
<script src="dist/lib/uploader/zui.uploader.min.js"></script>
<script type="text/javascript">

	$('#uploaderExample').uploader({
		autoUpload : true, // 當選擇文件後立即自動進行上傳操作
		url : 'upload.act',// 文件上傳提交地址
		responseHandler : function(responseObject, file) {
			console.log(responseObject);
			console.log(file);
			var str='';
			 str+='<input type="hidden" id="fileName" value="'+file.name+'">';
			 str+='<input type="hidden" id="fileType" value="'+file.type+'">';
			$("#fileContent").html(str);
			alert("已選擇好文件!");
		},
	});
	
	function upAll(){
		 var $fileName=$("#fileName");
		 var $fileType=$("#fileType");
		 var $fileIntro=$("#fileIntro");
		 var $fileScore=$("#fileScore");
		 if($fileIntro.val()==""){
			 alert("文件簡介不能爲空!");
		 }else if($fileScore.val()==""){
			 alert("請輸入下載積分!");
		 }else{
		 $.ajax({
			url:"upAll.act",
			type:"post",
			dataType:"JSON",
			data:{"fileName":$fileName.val(),"fileIntro":$fileIntro.val(),
				   "fileType":$fileType.val(),"fileScore":$fileScore.val()},
				   
			success:function(data){
				window.alert(data.msg);
				 window.history.go(-1);
			},
			error:function(data){
				alert("請聯繫管理員!");
			}
		})
	  }
	}
</script>
</html>

1.3.選擇文件:

HTML:

<div id="uploaderExample" class="uploader">
				<div class="file-list" data-drag-placeholder="請拖拽文件到此處"></div>
				<button type="button" class="btn btn-primary uploader-btn-browse">
					<i class="icon icon-cloud-upload"></i> 選擇文件
				</button>
			</div>

JS:訪問後臺接口:upload.act,把自己選擇的文件提交到對應的地址

$('#uploaderExample').uploader({
		autoUpload : true, // 當選擇文件後立即自動進行上傳操作
		url : 'upload.act',// 文件上傳提交地址
		responseHandler : function(responseObject, file) {
			console.log(responseObject);
			console.log(file);
			var str='';
			 str+='<input type="hidden" id="fileName" value="'+file.name+'">';
			 str+='<input type="hidden" id="fileType" value="'+file.type+'">';
			$("#fileContent").html(str);
			alert("已選擇好文件!");
		},
	});

後臺接口:我是把文件夾放到了D盤,要放到服務器自己修改一下路徑

@PostMapping("upload.act")
	public JsonMessage upload(HttpServletRequest request,MultipartFile file) {	
		System.out.println("file.getName():"+file.getName()); // 上傳的文件類型
		System.out.println("file.getOriginalFilename():"+file.getOriginalFilename()); // 文件名稱
		System.out.println("file.isEmpty():"+file.isEmpty()); // 文件是否爲空
		System.out.println("file.getContentType():"+file.getContentType()); // 文件類型 image/gif
		//將文件保存到D盤
		try {
			FileUtils.copyInputStreamToFile(file.getInputStream(), new File("D://"+file.getOriginalFilename()));
		} catch (IOException e) {
			e.printStackTrace();
		}	
		JsonMessage msg=new JsonMessage();
		msg.setMsg("成功");
		return msg;
	}

前臺通過upload.act把文件上傳到服務器的某個位置,再通過responseHandler回調函數把file參數傳過來,最後通過拼接的方法把文件名和文件類型拼接到頁面上。

 1.4.上傳文件:

用戶:輸入文檔簡介和下載積分

JS:訪問後臺接口:upAll.act,把這四項數據插入到數據庫中

function upAll(){
		 var $fileName=$("#fileName");
		 var $fileType=$("#fileType");
		 var $fileIntro=$("#fileIntro");
		 var $fileScore=$("#fileScore");
		 if($fileIntro.val()==""){
			 alert("文件簡介不能爲空!");
		 }else if($fileScore.val()==""){
			 alert("請輸入下載積分!");
		 }else{
		 $.ajax({
			url:"upAll.act",
			type:"post",
			dataType:"JSON",
			data:{"fileName":$fileName.val(),"fileIntro":$fileIntro.val(),
				   "fileType":$fileType.val(),"fileScore":$fileScore.val()},
				   
			success:function(data){
				window.alert(data.msg);
				 window.history.go(-1);
			},
			error:function(data){
				alert("請聯繫管理員!");
			}
		})
	  }
	}

後臺接口:

要插入兩張表,1張表是文件信息表,1張表是文件審覈表,上傳的文檔只有通過文件審覈後才能提供給用戶下載使用。

注意:如果後臺文檔類型沒有配置的話,比如數據庫插入的文檔類型名稱不符合規範的話,就無法通過文件類型名稱返回文件類型對象,就無法得到對應的Id,上傳文件操作就會失敗。

因爲前臺傳過來的參數只有文件類型名稱,沒有文件類型Id,所以要先通過文件類型名稱返回文件類型這個對象,然後從這個對象中取出文件類型Id插入到文件信息表中。

在文件信息表插入成功後,會生成自增的文件Id,我們從文件信息表中取出這個文件Id插入到文件審覈表中。

// 上傳文件
	@PostMapping("upAll.act")
	public JsonMessage upFile(HttpServletRequest request) {
		// 1.插入文件信息表
		UserInfo userInfo = (UserInfo) request.getSession().getAttribute("userInfo");
		Long userId = userInfo.getUserId();
		//前臺傳過來的值
		String fileName = request.getParameter("fileName");
		String fileIntro = request.getParameter("fileIntro");
		String fileType=request.getParameter("fileType");
		//通過文件類型返回文件類型這個對象,再從這個對象中取出文件類型Id
		FileType type=typeImpl.selectFtId(fileType);
		Long ftId =type.getFtId();
		String fileScores = request.getParameter("fileScore");
		Long fileScore = Long.parseLong(fileScores);
		String savePath ="D://"+fileName;
		FileInfo fileInfo = new FileInfo();
		fileInfo.setFileName(fileName);
		fileInfo.setFileIntro(fileIntro);
		fileInfo.setTypeId(ftId);
		fileInfo.setUserId(userId);
		fileInfo.setSavePath(savePath);
		fileInfo.setFileScore(fileScore);
		Integer fileInfoIndex = impl.insertByFileInfo(fileInfo);
		Long fileId = fileInfo.getFileId();
		System.out.println(fileId);
		// 2.插入文件審覈表
		FileCheck fileCheck = new FileCheck();
		fileCheck.setFileId(fileId);
		Integer fileCheckIndex = impl.insertByFileCheck(fileCheck);
		JsonMessage msg = new JsonMessage();
		if (fileInfoIndex > 0 && fileCheckIndex > 0) {
			msg.setId(1);
			msg.setMsg("上傳文件成功!");
		} else {
			msg.setId(2);
			msg.setMsg("上傳文件失敗!");
		}
		return msg;
	}

如果上傳成功後,返回到搜索文件頁面。

這裏涉及到了三張表,一張表是文件信息表,一張表是文件審覈表,一張表是文件類型表

文件審覈表:

文件信息表:

文件類型表:

2.文件審覈:

2.1.管理端審覈確認文件通過(比如把文件狀態從0改爲1)後,這時候,前臺用戶就可以查詢到審覈通過的文件。

3.文件下載:

3.1.首先看一下下載界面:

3.2.界面代碼:

<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="css/adminOther.css">
<link rel="stylesheet" href="dist/css/zui.min.css">
</head>

<body>
	<div class="wrapper">
		<div class="header">
			<nav class="navbar navbar-default" role="navigation">
				<div class="container-fluid">
					<!-- 導航頭部 -->
					<div class="navbar-header">
						<!-- 移動設備上的導航切換按鈕 -->
						<button type="button" class="navbar-toggle" data-toggle="collapse"
							data-target=".navbar-collapse-example">
							<span class="sr-only">切換導航</span> <span class="icon-bar"></span>
							<span class="icon-bar"></span> <span class="icon-bar"></span>
						</button>

					</div>
					<!-- 導航項目 -->
					<div class="collapse navbar-collapse navbar-collapse-example">
						<ul class="nav navbar-nav navbar-left">
							<li id="userInfoSession"></li>
						</ul>
						<!-- 一般導航項目 -->
						<ul class="nav navbar-nav navbar-right">
							<li><a href="javascript:void(0)" οnclick="oneself()">個人信息</a></li>
							<li><a href="javascript:void(0)" οnclick="myPointBefore()">我的積分</a></li>
							<li><a href="javascript:void(0)" οnclick="myDocuBefore()">我的文檔</a></li>
							<li><a href="javascript:void(0)" οnclick="upDocuBefore()">我要上傳</a></li>
							<li><a href="#">我要下載</a></li>
							<li><a href="javascript:void(0)" οnclick="ceShi()">測試上傳</a></li>
							<li><a href="javascript:void(0)" οnclick="loginOut()">退出</a></li>
						</ul>
					</div>
				</div>
			</nav>
		</div>
		<div class="conter" style="flex-direction: column;">
			<div class="panel"
				style="width: 80%; height: 200px; margin: 20px auto;">
				<div class="panel-heading"
					style="text-align: center; font-size: 18px; font-weight: bold;">
					文檔搜索</div>
				<div class="panel-body">
					<div class="col-xs-10">
						<div class="input-group with-padding">
							<span class="input-group-addon">文檔名稱</span> <input type="text"
								class="form-control" id="fileName" placeholder="請輸入文檔名稱">
						</div>
					</div>
					<div class="col-xs-2">
						<div class="with-padding">
							<button class="btn btn-block" οnclick="search()" type="button">搜索文檔</button>
						</div>
					</div>
				</div>
			</div>
			<div class="panel" style="width: 80%; margin: 20px auto;">
				<div class="panel-heading"
					style="text-align: center; font-size: 18px; font-weight: bold;">
					搜索結果</div>
				<div class="panel-body">
					<table class="table table-bordered" id="tableDataGridExample">
						<thead>
							<tr>
								<th>文件標題</th>
								<th>上傳人</th>
								<th>上傳時間</th>
								<th>下載積分</th>
								<th>文檔類型</th>
								<th>操作</th>
							</tr>
						</thead>
						<tbody id="fileSearchBody">
						</tbody>
					</table>
					<div style="width: 300px; margin: 0 auto;">
						<input οnclick="pre()" type="button" value="上一頁" class="btn">
						<span id="page">0/0</span> <input οnclick="next()" type="button"
							value="下一頁" class="btn">
					</div>

				</div>
			</div>
		</div>
	</div>
</body>
<script src="dist/lib/jquery/jquery.js"></script>
<script src="dist/js/zui.min.js"></script>
<script type="text/javascript">

function ceShi(){//測試上傳
	$.ajax({
		url:"ceShiQian.act",
		type:"post",
		dataType:"JSON",
		success:function(data){
			if(data.id==1){
				window.location.href="page.act?page="+data.location+ "&oneself=" + Math.random();
			}
		},
		error:function(data){
			alert("請聯繫管理員!");
		}
	});	
	
}



function timestampToTime(timestamp) {
	   var date = new Date(timestamp);//時間戳爲10位需*1000,時間戳爲13位的話不需乘1000
	   Y = date.getFullYear() + '-';
	   M = (date.getMonth()+1 < 10 ? '0'+(date.getMonth()+1) : date.getMonth()+1) + '-';
	   D = date.getDate() + ' ';
	   h = date.getHours() + ':';
	   m = date.getMinutes() + ':';
	   s = date.getSeconds();
	   return Y+M+D;
}

//初始化搜索條件參數
var fileName='';
//定義分頁變量
var count=0;//一共多少條數據
var limit=5;//每頁顯示多少條數據
var start=0;//從哪開始
var end=4;//到哪結束
var allPage=1;//一共多少頁
var currPage=1;//當前在第幾頁
//定義一個全局變量保存分頁的用戶信息
var fileSearchArr=null;

function initPage(){//加載分頁數據
	 $.ajax({
		   url:"fileSearch.act",
		   type:"post",
		   dataType:"JSON",
		   data:{"fileName":fileName, "start":start,"limit":limit},
		   success:function(data){
			   console.log(data.dataList);
			   //保存搜索的數量數據
			   count=data.dataList.count;
			   var arr=data.dataList.fileSearch;
			   fileSearchArr=arr;
			   var str='';
			   for(var i=0;i<arr.length;i++){
				   str+='<tr>';
				   str+='<td>'+arr[i].fileInfo.fileName+'</td>';
				   str+='<td>'+arr[i].userInfo.userName+'</td>';
				   str+='<td>'+timestampToTime(arr[i].fileInfo.upCtime)+'</td>';
				   str+='<td>'+arr[i].fileInfo.fileScore+'</td>';
				   str+='<td>'+arr[i].fileType.typeName+'</td>';
				   str+='<td>';
				   str+='<a class="btn btn-block" href="download.act?fileId='+arr[i].fileId+'">下載該文件</a>';			  		   		   
				   str+='</td>';
				   str+='</tr>';
			   }
			   $("#fileSearchBody").html(str);
			   
			   //分頁數據展示
				  allPage=count % limit ==0 ?(count/limit):(parseInt(count/limit+1));
						  $("#page").html(currPage+"/"+allPage);
		   },
		   error:function(data){
			   alert("請聯繫管理員!");
		   }
		   
	 })
}
initPage();

//上一頁
 function pre() {
		   if(currPage == 1){
				alert('這已經是第一頁了');
			}else{
				currPage--;
				start -= limit;
				end -= limit;
				initPage();
			}
   }
//下一頁
function next() {
	   if(currPage == allPage){
			alert('這已經是最後一頁了');
		}else{
			currPage++;
			start += limit;
			end += limit;
			initPage();
		}
   }
   
function search(){//查詢
	// 將所有分頁數據初始化
	count = 0; // 一共找到多少條數據
	limit = 5; // 每頁顯示多少條數據
	start = 0; // 從哪裏開始找數據
	end = 4; // 到哪裏結束
	allPage = 1; // 一共多少頁
	currPage = 1; // 當前在第幾頁
	// 將搜索框的數據賦值給搜索的全局變量
	fileName = $('#fileName').val();
	// 初始化頁面
	initPage();
}
  
function myPointBefore(){//跳轉到我的積分界面
	$.ajax({
		url:"userScoreBefore.act",
		type:"post",
		dataType:"JSON",
		success:function(data){
			if(data.id==1){
				window.location.href="page.act?page="+data.location+ "&oneself=" + Math.random();
			}
		},
		error:function(data){
			alert("請聯繫管理員!");
		}
	});	
}

function oneself(){//跳轉到個人信息界面
	$.ajax({
		url:"oneself.act",
		type:"post",
		dataType:"JSON",
		success:function(data){
			if(data.id==1){
				window.location.href="page.act?page="+data.location+ "&oneself=" + Math.random();
			}
		},
		error:function(data){
			alert("請聯繫管理員!");
		}
	});
}




function upDocuBefore(){//跳轉到上傳文檔界面
	$.ajax({
		url:"upFileBefore.act",
		type:"post",
		dataType:"JSON",
		success:function(data){
			if(data.id==1){
				window.location.href="page.act?page="+data.location+ "&upDocuBefore=" + Math.random();
			}
		},
		error:function(data){
			alert("請聯繫管理員!");
		}
	});
}

function myDocuBefore(){//跳轉到我的文檔界面
	$.ajax({
		url:"myFileBefore.act",
		type:"post",
		dataType:"JSON",
		success:function(data){
			if(data.id==1){
				window.location.href="page.act?page="+data.location+ "&myFileInfo=" + Math.random();
			}
		},
		error:function(data){
			alert("請聯繫管理員!");
		}
	});
}

function loginOut(){
	if(confirm("確定要退出登錄嗎?")){
		$.ajax({
			url:"loginOut.act",
			type:"post",
			dataType:"JSON",
			success:function(data){
				if(data.id==1){
					alert(data.msg);
					window.location.href="page.act?page="+data.location;
				}
			},
			error:function(data){
				alert("請聯繫管理員!");
			}
		});
	   }
}

//從session中取出用戶信息
function userInfoSession(){
	   $.ajax({
		   url:"userSession.act",
		   type:"post",
		   dataType:"JSON",
		   success:function(data){
			   console.log(data);
			   var arr=data.dataList.userInfo;
			   var str='';
			   str+='<a href="javascript:void(0);">歡迎您,'+arr.userName+"用戶,  當前積分: "+arr.userScore+'</a>';
			   $('#userInfoSession').html(str);
		   },
		   error:function(data){
			   alert("請聯繫管理員!");
		   }
	   })
}
userInfoSession();

</script>
</html>

3.3.我們通過四張表連表查詢:查詢出搜索文檔列表

3.4.通過循環,循環出列表並得到對應的文件Id,這時候我們使用GET請求去請求數據

3.5.前臺:請求地址後面拼接上文件Id,把文件Id傳給後臺,點擊下載該文件的a標籤訪問後臺接口

3.6.後臺接口:接收前臺傳過來的文件Id,通過文件Id去數據庫中找到對應的文件信息對象,再從這個對象中找到相應的文件名該文件保存的路徑,以流的形式下載下來。

@Resource
	private FileInfoServiceImpl impl;
	
	@GetMapping("download.act")
	public void download(HttpServletRequest request,HttpServletResponse response) throws IOException {	
		//文件Id
		String fileIds=request.getParameter("fileId");
		Long fileId=Long.parseLong(fileIds);
		//通過文件Id找文件信息對象
		FileInfo info=impl.selectPath(fileId);
		//文件名
		String filename=info.getFileName();
		//保存的路徑
		String path=info.getSavePath();
		//獲取輸入流  
		InputStream bis = new BufferedInputStream(new FileInputStream(new File(path)));
		//轉碼,免得文件名中文亂碼  
		filename = URLEncoder.encode(filename,"UTF-8");  
		//設置文件下載頭  
		response.addHeader("Content-Disposition", "attachment;filename=" + filename);  
		//1.設置文件ContentType類型,這樣設置,會自動判斷下載文件類型    
		response.setContentType("multipart/form-data");   
		BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());  
		int len = 0;  
		while((len = bis.read()) != -1){  
			out.write(len);  
			out.flush();  
		}  
		out.close();  
	}

4.演示:

4.1.桌面有個文件

4.2.上傳文件

4.3.後臺審覈文件

4.4.後臺審覈通過,前臺可以下載該文件

4.5.下載後

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章