今天接到命令要求在微信小程序中的專家問答模塊里,添加一個在提問時可以上傳附件的功能(doc.xls.ppt.pdf).
首先梳理一下流程:
1.用戶點擊“上傳”按鈕選擇附件后,將附件首先上傳到臨時文件夾下,我選在放在tomcat編譯后的文件夾中。
2.當用戶完善提問內容,點擊“發布問題”之后,將附件從臨時文件夾中轉存到正式的資源庫中。
3.其他用戶點開問題后,通過“打開附件”按鈕下載瀏覽附件。
因為我是萌新,而且閱讀我隨筆很多也是萌新,所以在這里首先提一下困擾了我很久的在服務器環境中文件存儲過程中相對、絕對路徑,以及最關鍵的數據庫存儲路徑的問題,以下:)
1.首先在File對象構造函數中,提供的文件地址必須是絕對路徑或url地址,不能使用使用相對路徑,因此,不管是正式資源庫,還是臨時文件庫,我們都要獲取絕對路徑;
-正式資源庫好解決,因為是自己創建的文件夾,可以直接使用類似,"C://expertFile/"+文件名的方式創建File對象。
-臨時文件夾我們可以使用request對象獲取session對象,然后獲取tomcat編譯文件的根目錄,request.getSession().getServletContext().getRealPath("expertFile")+文件名的方式創建File對象
2.好,這是存儲過程中徑路的解決辦法,但是這些都是本地路徑,數據庫中不可能存本地路徑,因為到了服務器環境下,讓用戶去本地去找附件肯定找不到,所以在數據庫中,我們采用URL
路徑存儲,URL路徑不止可以訪問項目的根目錄,還可以進行自定義配置。如下
其中Document base是你服務器的正式文件資源庫的地址,Path是你的URL地址。
然后用戶就可以通過 https://IP:端口/expertFile/+文件名 這樣的URL地址訪問並下載正式文件庫中的附件了。所以數據庫中存儲的是URL地址
這里需要注意一下在存儲的時候IP中一定不要存localhost要存服務器的IP地址。
路徑問題說明白之后,我開始正題,微信小程序開發
這里,我又遇到了一個問題,在微信小程序中,為了用戶的安全考慮,微信沒有提供讓用戶選擇本地文檔接口的API,但是翻找API的過程中,我發現了一個接口
“wx.chooseMessageFile”,這個接口允許用戶在自己的聊天記錄中選擇文檔進行上傳,於是我就想先把功能實現,選擇了這個接口。但是這個接口的作用僅僅是
將用戶選擇的文檔上傳到微信提供的一個臨時路徑中,你還需要把他下載到本地的臨時文件夾中,這個接口會返回一個上面說過的URL地址,接着我們使用
"wx.uploadFile"接口將請求傳遞到后台,進行處理,
下面貼一下微信小程序端的基本代碼,至於文件大小,格式校驗啥的,各位根據自己需求添加修改
接下來是后台代碼,其實路徑問題弄明白,我覺得就沒什么難點了
String path = request.getSession().getServletContext().getRealPath("expertFile"); //這里最好在做一下文件夾是否存在的判斷,我這里博客中就去掉了
String temporaryFilePath = file.getPath();
//首先根據微信小程序返回的臨時地址,從微信提供的URL地址讀取文件,這個file對象就是自動裝配的File類型的file對象
File temporaryFile = new File(temporaryFilePath);
if(temporaryFile.exists()){
BufferedInputStream is = new BufferedInputStream(new FileInputStream(temporaryFile));
ByteArrayOutputStream io = new ByteArrayOutputStream((int)file.length());
int buf_size = 4194304; //這里我限制了上傳附件最大為4M
byte[] bytes = new byte[buf_size];
int len = 0;
while(-1 != (len = is.read(bytes,0,buf_size))){
io.write(bytes,0,len);
}
}
//拿到文件的byte之后,下面的代碼是存儲到臨時文件夾中
String filepath = path+文件名;
File file2 = new File(filepath);
FileOutputStream stream = new FileOutputStream(file2);
BufferedOutputStream bo = new BufferedOutputStream(stream);
bo.write(io.toByteArray());
//記得關閉連接
is.close();
io.close();
stream.close();
bo.close();
好了現在,用戶上傳的附件已經存儲到了本地臨時文件夾,至於臨時文件夾到正式文件資源庫的過程,和轉存臨時文件的過程一樣,就不再贅述,關鍵點也都說了,就是數據庫的存儲地址。
現在說最后一步,用戶打開瀏覽附件
這一步更加簡單,沒有后台操作:
微信的API提供了兩個接口“wx.downloadFile”和“wx.openDocument”分別負責下載和打開文檔,你只需要從后台數據庫查找出URL地址就可以了。