文件上傳的思路:
我們需要先上傳文件,將文件信息進行上傳,然後通過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.下載後