java web項目 使用elfinder 實現文件管理器

  目的在客戶端(瀏覽器)上像操做window系統中的文件/文件夾同樣,操做服務器上的某些指定文件/文件夾javascript

  效果圖:php

  

  框架:jsp + springMVC + Tomcatcss

  前臺使用 elfinderhtml

  這是一個很好用的開源web文件管理器插件,用jquery+jquery-ui寫的,在網上一搜文檔好像也挺多的,因而準備搬到項目中來(挖坑開始),瞭解事後發現做者附帶的後臺demo是php寫的,大多文檔資料也是php的,java的特別少,出了問題也不知道是爲何,急死我的,先後折騰了兩天才勉強能用了,在這裏記錄一下,以供你們參考,本人菜鳥,若是有什麼理解不對的地方,歡迎各位指正。前端

  打開官網,把代碼dow下來:java

  

  打開壓縮包:把選中的這些文件拷到項目中:jquery

  

  選中的可能有用,沒選中的確定沒用(爲何?由於這沒拷進項目裏他也能跑,並且沒問題...)git

  

  後臺使用的是一個大神開源的基於java實現demo  elfinder-2.x-servletgithub

  這個目前還在持續更新中web

  接下來開始配置吧,基礎版:

  Maven項目中添加依賴項

1 <!-- web文件夾管理器jar包 -->
2     <dependency>
3         <groupId>com.github.bluejoe2008</groupId>
4         <artifactId>elfinder-servlet-2</artifactId>
5         <version>1.2</version>
6         <classifier>classes</classifier>
7     </dependency>

  或者直接點擊下載 elfinder-servlet-2.jar 包放到lib目錄下

  接下來在servlet.xml中配置須要spring管理的各對象

 1 <!-- find appropriate command executor for given command-->
 2 <bean id="commandExecutorFactory"
 3  class="cn.bluejoe.elfinder.controller.executor.DefaultCommandExecutorFactory">
 4     <property name="classNamePattern"
 5  value="cn.bluejoe.elfinder.controller.executors.%sCommandExecutor" />
 6     <property name="map">
 7         <map>
 8         <!-- 
 9  <entry key="tree"> 10  <bean class="cn.bluejoe.elfinder.controller.executors.TreeCommandExecutor" /> 11  </entry> 12         -->
13         </map>
14     </property>
15 </bean>
16 
17 <!-- FsService is often retrieved from HttpRequest -->
18 <!-- while a static FsService is defined here -->
19 <bean id="fsServiceFactory" class="cn.bluejoe.elfinder.impl.StaticFsServiceFactory">
20     <property name="fsService">
21         <bean class="cn.bluejoe.elfinder.impl.DefaultFsService">
22             <property name="serviceConfig">
23                 <bean class="cn.bluejoe.elfinder.impl.DefaultFsServiceConfig">
24                     <property name="tmbWidth" value="80" />
25                 </bean>
26             </property>
27             <property name="volumeMap">
28                 <!-- two volumes are mounted here -->
29                 <map>
30                     <entry key="A">
31                         <bean class="cn.bluejoe.elfinder.localfs.LocalFsVolume">
32                             <property name="name" value="MyFiles" />
33                             <property name="rootDir" value="/tmp/a" />
34                         </bean>
35                     </entry>
36                     <entry key="B">
37                         <bean class="cn.bluejoe.elfinder.localfs.LocalFsVolume">
38                             <property name="name" value="Shared" />
39                             <property name="rootDir" value="/tmp/b" />
40                         </bean>
41                     </entry>
42                 </map>
43             </property>
44             <property name="securityChecker">
45                 <bean class="cn.bluejoe.elfinder.impl.FsSecurityCheckerChain">
46                     <property name="filterMappings">
47                         <list>
48                             <bean class="cn.bluejoe.elfinder.impl.FsSecurityCheckFilterMapping">
49                                 <property name="pattern" value="A_.*" />
50                                 <property name="checker">
51                                     <bean class="cn.bluejoe.elfinder.impl.FsSecurityCheckForAll">
52                                         <property name="readable" value="true" />
53                                         <property name="writable" value="true" />
54                                     </bean>
55                                 </property>
56                             </bean>
57                             <bean class="cn.bluejoe.elfinder.impl.FsSecurityCheckFilterMapping">
58                                 <property name="pattern" value="B_.*" />
59                                 <property name="checker">
60                                     <bean class="cn.bluejoe.elfinder.impl.FsSecurityCheckForAll">
61                                         <property name="readable" value="true" />
62                                         <property name="writable" value="false" />
63                                     </bean>
64                                 </property>
65                             </bean>
66                         </list>
67                     </property>
68                 </bean>
69             </property>
70         </bean>
71     </property>
72 </bean>

   這裏配置就是服務器上的文件夾名稱,服務器上是在你有tomcat所在盤的根目錄下建一個叫tmp的文件夾,但在客戶端(瀏覽器)上顯示的就是你配置的名稱:MyFiles

   

  加載jar包後,爲了查看後臺接收數據的url,須要加載源文件(我給的jar包壓縮包裏)

  

  咱們打開這個類cn.bluejoe.elfinder.controller.ConnectorController能夠看到映射路徑爲」connector」,這就是前臺請求後臺時的url路徑(先暫時記住)

  

  看到這裏的@controller,說明這就是後臺的接收全部請求的入口,要讓springmvc管理這個類,咱們須要在springmvc-servlet.xml中加入這個類所在包的掃描

<context:component-scan base-package="cn.bluejoe.elfinder.controller" />

  

  接着開始寫前臺頁面(我用的是jsp頁面):

  能夠直接拿elfinder那個包裏的elfinder.html改,但他裏面沒有引入js和css,因此仍是本身來寫吧

  最好按照下面給出的順序導入,由於在最開始我沒有注意,致使不少樣式是亂的,響應到了錯誤的地方

  導入jquery.js,版本稍高的好,由於我發現他的裏面用的是jquery-3.*的版本,這個根據本身的路徑來導  

<script src="${pageContext.request.contextPath}/js/jquery-3.2.1.min.js" type="text/javascript" charset="utf-8"></script>

  導入jquery-ui.js jquery-ui.css ,接下來的這些文件的路徑都是根據最開始拷到項目中的elfinder包裏去找

<link href="${pageContext.request.contextPath}/elfinder/jquery/jquery-ui-1.12.0.css" rel="stylesheet" type="text/css" media="screen" charset="utf-8"> 
<script src="${pageContext.request.contextPath}/elfinder/jquery/jquery-ui-1.12.0.js" type="text/javascript" charset="utf-8"></script>

  導入elfinder.css、theme.css

<link rel="stylesheet" href="${pageContext.request.contextPath}/elfinder/css/elfinder.min.css" type="text/css" media="screen" charset="utf-8">
<link rel="stylesheet" href="${pageContext.request.contextPath}/elfinder/css/theme.css" type="text/css" media="screen" charset="utf-8">

  導入elfinder.js

<script src="${pageContext.request.contextPath}/elfinder/js/elfinder.min.js" type="text/javascript" charset="utf-8"></script>

  導入中文語言包elfinder.zh_CN.js,elfinder是支持國際化的,從2.0版本開始能夠完美支持中文了,若是這裏不導入,不配置,默認是英文的

<script src="${pageContext.request.contextPath}/elfinder/js/i18n/elfinder.ru.js" type="text/javascript" charset="utf-8"></script>
<script src="${pageContext.request.contextPath}/elfinder/js/i18n/elfinder.zh_CN.js" type="text/javascript" charset="utf-8"></script>

  在html標籤中聲明容器:

<div id="elfinder" ></div>

  Js代碼:

<script type="text/javascript" charset="utf-8"> $(document).ready(function() { $('#elfinder').elfinder({ url : '${pageContext.request.contextPath}/connector',    //這裏的請求地址對應controller中的地址 lang : 'zh_CN',        //配置默認語言爲中文
            height : parseInt(window.screen.availHeight * 0.7)        //配置高度爲瀏覽器高度的0.7
 }); }); </script>

  此時啓動項目應該能看到如下頁面了

  此時一個坑出現了,我傳什麼文件都提示「未知的命令:null」,以及後臺提示:unknown command:null,  google了幾個小時才發現是因數servlet.xml中配置了

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="defaultEncoding" value="UTF-8" />
        <property name="maxUploadSize" value="104857600" />
        <property name="maxInMemorySize" value="2048" />
</bean>

  兩個衝突了,去掉CommonsMultipartResolver就能夠,可是項目中其餘地方用到的上傳就沒法使用了,度娘了好久說衝突能夠寫一個代理來解決(不太會),直接把別人的代碼拿來(好幾百行),發現並沒卵用,氣死我的,因而又開始瘋狂搜索...

  最後發現根本不用什麼代理,CommonsMultipartResolver這個類中有一個public boolean isMultipart(HttpServletRequest request)方法,咱們繼承這個類,重寫這個isMultipart方法返回true和false就能夠達到是否使用這個類來處理上傳了

  此處使用攔截器來判斷其是咱們的elfinder的上傳文件或是其餘上傳方式,這裏主要是用請求url的方式來判斷是否爲elfinder的請求,分三個類,代碼以下:

import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; public class MultipartContextFileter implements Filter { FilterConfig config; @Override public void destroy() { } @Override public void doFilter(ServletRequest srequest, ServletResponse sresponse, FilterChain chain) throws IOException, ServletException { boolean isData = false; HttpServletRequest req = (HttpServletRequest)srequest; // 根據web.xml中的配置,判斷當前url是否跳過此過濾器
        String excludeURL = config.getInitParameter("excludeURL"); if (excludeURL != null && !"".equals(excludeURL)) { if (req.getRequestURI().indexOf(excludeURL) != -1) { isData = true; } } if (isData) { String content_type = req.getContentType(); if (content_type != null && content_type.indexOf("multipart/form-data") != -1) { MyMultiPartRequest jakarta = new MyMultiPartRequest(req); jakarta.isData = true; req = jakarta; } } chain.doFilter(req, sresponse); } @Override public void init(FilterConfig arg0) throws ServletException { config = arg0; } }
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper;  /**
  * 繼承request,對其進行包裝,以保存更多信息,用於保存判斷是不是elfinder的請求,後面執行時能夠判斷是否跳過CommonsMultipartResolver的處理
  */ public class MyMultiPartRequest extends HttpServletRequestWrapper { public boolean isData = false; //是否執行自定義的CommonsMultipartResolver public MyMultiPartRequest(HttpServletRequest request) { super(request); } }
public class CommonsMultipartResolver extends org.springframework.web.multipart.commons.CommonsMultipartResolver { /** * 這裏是處理Multipart http的方法。若是這個返回值爲true,那麼Multipart http * body就會MyMultipartResolver 消耗掉.若是這裏返回false * 那麼就會交給後面的本身寫的處理函數處理例如剛纔elfinder請求 * */ @Override public boolean isMultipart(HttpServletRequest request) { if(request instanceof MyMultiPartRequest){ MyMultiPartRequest trequest = (MyMultiPartRequest)request; if(trequest.isData){ return false; } } return super.isMultipart(request); } }

  而後在web.xml中配置攔截器,使其生效

<filter>
    <filter-name>MultiPartFilter</filter-name>
    <filter-class>com.sctbyc.sware.controller.resourceLibrary.filter.MultipartContextFileter</filter-class>
    <init-param>
        <param-name>excludeURL</param-name>
        <param-value>connector</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>MultiPartFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

  固然也不要忘記把本身剛剛寫的處理文件上傳的類配置到xml中,這樣就spring就會自動建立及調用咱們寫的這個類了

  

<bean id="multipartResolver" class="咱們定義的CommonsMultipartResolver這個類的全路徑名">
     <property name="defaultEncoding" value="UTF-8" />
     <property name="maxUploadSize" value="104857600" />
     <property name="maxInMemorySize" value="2048" />
</bean>

 

  好了,這下就能夠正常使用了上傳文件了,好TM開心,趕忙各類建文件夾,上傳文件

  此時第二個坑出現了(文件超過2M傳上去就是一個blob文件,且只有幾十k到1M多不等),第一反應這應該是個不完整的二進制文件,但爲何呢?F12打開瀏覽器,看了下發現上傳文件時它一直在不停的發請求,原來是這個前端框架使用的大文件分段上傳的技術,就是把一個文件切成不少小塊,一直髮請求,一點點的上傳,然後臺彷佛並無這樣實現,因此形成了這種狀況,至關於多大的文件,最後都只保存了最後一次上傳的那一塊,知道了緣由,開始查elfinder的文檔看看他怎麼說:果真還真有這樣一個配置項:

  他說默認是10M,這尋思也沒有啊,個人文件超過2M就不行了,因而我就配置了一個這個,再在後面加了兩個0,約等於1G了,再試,仍是不行啊,超過2M就截斷了,又開始查文檔,覺得是本身配置的姿式沒對,弄了好久,不行,沒辦法,只能看他的elfinder.full.js了,看看是否是這其中有什麼鬼,果真我發現了一個東西

  這裏默認爲2M-8K的大小,和咱們配置的大小中取一個,但使用的是Math.min,取得是其中小的一個,難怪咱們的大了他就不用了,所能咱們把他改爲Math.max就可使用咱們配置的大小了,媽媽不再用擔憂我給的容量不夠了,注意這裏查看的是elfinder.full.js(即原版),但咱們引入的時候是引入的elfinder.mini.js(壓縮版),因此要去mini.js中修改纔有用,(由於mini版沒有格式,很差找,這裏告訴你們一個小技巧,能夠Ctrl+F打開搜索框,搜索2097152,也就是上圖裏的數字,一下就找到了)(這裏測試的時候由於本地tomcat給的空間不夠,所報了一個OutMemoryError,內存溢出,不過不用擔憂,生產環境給的是16個G,隨便他傳)

  還有一個問題就是上傳時有一個選擇目錄,但好像支持得不太好,傳不上去,也不知道怎麼改,因此我索性就在elfinder.js中把這個給屏蔽了,過程以下:

  瀏覽器中檢查這個按鈕,發現他的html代碼爲:

<div class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only elfinder-tabstop elfinder-focus"><span class="ui-button-text">

  因此去elfinder.mini.js中搜索出來,在他以前加上一個判斷,若是是選擇目錄,就返回一個空:

if(i=='selectFolder')return '<span></span>';

  這裏等於selectFolder是由於在elfinder.zh_CN.js 中能夠找到 "選擇目錄"對應的英文就是「selectFolder」

 

  到這裏,基本配置就結束了,從使用上來講幾乎是沒有問題了。

  剩下的就該考慮到部分須要優化的內容了:還記得咱們最開始的時候說過,後臺的jar包中給定了請求的url了,但只有一個,這很容易衝突,特別是項目大了事後,更大機率會出現了,因此咱們就須要本身來定義url是最好的了,其次是權限的問題,特別是項目中涉及到一部分人能操做,一部分人只能查看、下載的問題,這個等下一篇再寫了。。。(拖延一下……^-^)

 

原文出處:https://www.cnblogs.com/aforever/p/10859828.html

相關文章
相關標籤/搜索