這個方法是讓我們可以不藉由Liferay後台,自行從前端把文件上傳上去。
首先我們的.jsp檔內要有上傳的tag如下;
<portlet:actionURL name="videoUpload" var="videoUploadURL">
</portlet:actionURL>
以上的action是一定要有的、
<aui:form action="<%=videoUploadURL.toString()%>" method="post" enctype="multipart/form-data">
<aui:input type="file" name="file" id="file" />
<aui:button type="submit" name="upLoad" value="完成" />
</aui:form>
以上的aui form包含了上傳文件視窗跟提交的按鈕,在這裡要注意的地方是action中的enctype="multipart/form-data"這個部分,
在一般的情況下,我們送出表單預設是
application/x-www-form-urlencoded(不顯示預設)
這是普通情況下送出網頁的編碼,但是如果我們要送出的網頁包含了檔案,就必須加上enctype="multipart/form-data"
但是在這種編碼之下,傳送到後端java檔時使用ParamUtil.getString(Request, "name");的時候會無法抓取到變數
所以必定要把其中的Request改成uploadRequest,這樣就可以在既有檔案又有表單要傳送時都可以順利存入了。
接下來就輪到後端的action.Java檔了
public void videoUpload(ActionRequest request, ActionResponse response)
throws Exception {//這個方法是兼上傳表單及上傳檔案的方法
ThemeDisplay themeDisplay = (ThemeDisplay) request
.getAttribute(WebKeys.THEME_DISPLAY);
PortletURL portletUrl = PortletURLFactoryUtil.create(request,
"ISUOCWAdmin_WAR_ISUOCWportlet", themeDisplay.getPlid(),
PortletRequest.RENDER_PHASE);
跟傳送表單一樣,先寫一個方法出來,前面大致上都一樣。
接著是將檔案上傳至後端。
UploadPortletRequest uploadRequest = PortalUtil.getUploadPortletRequest(request); 創建出上傳的request物件
String submissionFileName = uploadRequest.getFileName("file");//uploaded filename
String contentType = uploadRequest.getContentType("file"); //uploaded file you can see it in /tomcat/temp
long size = uploadRequest.getSize("file");
InputStream is = uploadRequest.getFileAsStream("file");
可以看到取得檔案名稱,檔案類型,大小跟串流的寫法,這裡的file是根據剛才jsp網頁內上傳視窗所設定的name來抓的
以下是為了將檔案存入liferay內的資料庫做準備。
long userId = themeDisplay.getUserId(); //用戶名稱
long repositoryId = 10802; //存儲Id,一般而言是取groupID
long folderId = 10924;
//以上這個是資料夾Id,這裡先用預設的文件夾
String sourceFileName = submissionFileName; //文件名稱
String mimeType = MimeTypesUtil.getContentType(submissionFileName);//文件類型,可以用MimeType的方法去抓取
String title = ParamUtil.getString(uploadRequest, "courseName");
//文件標題,可修改的,我在這裡把文件標題設定成跟課程名稱一樣,如果有重複的會出錯。
String description = ""; //文件的描述
String changeLog = "";//文件修改紀錄
ServiceContext serviceContext = ServiceContextFactory.getInstance(DLFileEntry.class.getName(), uploadRequest);
//裡面包含了一些環境信息,如groupid,companyid,權限,門戶路徑,當前語言,userId等信息。
//在實際應用中可以自己將上面的這個接口再做一層封裝使用。
serviceContext.setAddGuestPermissions(true); //很神奇的,用這個方法去設定訪客權限。
FileEntry fileEntry = DLAppLocalServiceUtil.addFileEntry(userId, repositoryId, folderId, sourceFileName, mimeType, title, description, changeLog, is, size, serviceContext);
//這一行是正式把上傳的文件放入document中,然後存在fileEntry物件裡備用。
由於我還有表單跟著一起被POST出去,所以就用uploadRequest抓取表單的數值,同時也使用剛才的fileEntry物件獲取了一些必要的欄位
uploadRequest.cleanUp();//加上這個可以把temp裡的暫存檔案清除。
最後再呼叫新增的方法就完成了。
最後還有抓取該上傳的文件路徑,以下定義一個抓路徑的方法;
public static String getFilePath(FileEntry fileEntry) {
if (null!=fileEntry) {
return "/documents/" + fileEntry.getRepositoryId() + "/" + fileEntry.getFolderId() + "/"
+ HttpUtil.encodeURL(HtmlUtil.unescape(fileEntry.getTitle()), true) + "/" + fileEntry.getUuid();
}else {
//如有需要,此處可以定義一個默認圖片
return StringPool.BLANK;
}
至此檔案的上傳算是完成了!
(補充)
如果沒有欄位存上傳路徑時,可以使用以下這個方法;
String local=themeDisplay.getPortalURL()+themeDisplay.getPathContext();
以上是抓本機路徑,document前面那一段。
String thumbURL = local+"/documents/"+fileEntry.getGroupId()+"/"
+fileEntry.getFolderId()+"/"+fileEntry.getTitle();
接下來就是抓取完整路徑,只要資料庫中有事先存fileEntryID就可以抓取了!
