UEditor WEB-INF目錄訪問與自定義上傳

UEditor很好用,但是它的圖片默認是上傳到項目中,重新部署項目后之前的圖片全會被刪掉(坑爹),為了實現把圖片傳到其他地方,如阿里云的OSS(不是打廣告),可以進行以下改造實現。

后端配置

  1. 下載的包里面./jsp/lib有5個jar包,其中commons-*.jarjson.jar可通過maven下載,ueditor-*.jarMaven上有但是不是官方上傳的,所以我手動導入到項目
  2. 把整個包復制到項目資源目錄,如放到WEB-INF目錄下還要通過一下特殊配置,如直接放到webapp目錄下可參考官方文檔
  3. 假設插件放置位置為WEB-INF/assets/plugins/ueditor,因為WEB-INF目錄下內容不能直接訪問,ueditor/jsp/controller.jsp是無法配置的,所以需要通過Spring Mvc中的Controller轉發訪問
  4. 項目新建一個Controller并配置RequestMapping
    Controller
@Controller
@RequestMapping("/ueditor")
public class UEditorController {

    /**
     * UEditor 入口
     *
     * @return
     */
    @RequestMapping("/controller")
    public String controller() {
        return "common/_ueditor";
    }
}

common/_ueditor.jsp

<jsp:forward page ="/WEB-INF/assets/plugins/ueditor/jsp/controller.jsp" />
  1. 在要調用ueditor的頁面配置ueditor
<!--配置文件-->
<script src="<%=request.getContextPath()%>/assets/plugins/ueditor/ueditor.config.js"></script>
 <!--必須放到ueditor.config.js之后,ueditor.all.mim.js之前,路徑根據實際情況修改-->
<script>
    window.UEDITOR_CONFIG.serverUrl = "<%=request.getContextPath()%>/ueditor/controller"
</script>
<!-- 編輯器源碼文件 -->
<script src="<%=request.getContextPath()%>/assets/plugins/ueditor/ueditor.all.min.js"></script>
  1. 到此ueditor的后端配置完成,調用方法可參考官方文檔

改造

1.重寫ActionEnter類

import com.baidu.ueditor.ConfigManager;
import com.baidu.ueditor.define.ActionMap;
import com.baidu.ueditor.define.BaseState;
import com.baidu.ueditor.define.State;
import com.baidu.ueditor.hunter.FileManager;
import com.baidu.ueditor.hunter.ImageHunter;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * Created by GustinLau on 2017-05-11.
 */
public class ActionEnter extends com.baidu.ueditor.ActionEnter {
    private HttpServletRequest request = null;
    private String rootPath = null;
    private String contextPath = null;
    private String actionType = null;
    private ConfigManager configManager = null;

    public ActionEnter(HttpServletRequest request, String rootPath) {
        super(request, rootPath);
        this.request = request;
        this.rootPath = rootPath;
        this.actionType = request.getParameter("action");
        this.contextPath = request.getContextPath();
        this.configManager = ConfigManager.getInstance(this.rootPath, this.contextPath, request.getRequestURI());
    }

    @Override
    public String invoke() {
        if(this.actionType != null && ActionMap.mapping.containsKey(this.actionType)) {
            if(this.configManager != null && this.configManager.valid()) {
                State state = null;
                int actionCode = ActionMap.getType(this.actionType);
                Map<String, Object> conf = null;
                switch(actionCode) {
                    case 0:
                        return this.configManager.getAllConfig().toString();
                    case 1:
                    case 2:
                    case 3:
                    case 4:
                        conf = this.configManager.getConfig(actionCode);
                        state = (new Uploader(this.request, conf)).doExec();
                        break;
                    case 5:
                        conf = this.configManager.getConfig(actionCode);
                        String[] list = this.request.getParameterValues((String)conf.get("fieldName"));
                        state = (new ImageHunter(conf)).capture(list);
                        break;
                    case 6:
                    case 7:
                        conf = this.configManager.getConfig(actionCode);
                        int start = this.getStartIndex();
                        state = (new FileManager(conf)).listFile(start);
                }

                return state.toJSONString();
            } else {
                return (new BaseState(false, 102)).toJSONString();
            }
        } else {
            return (new BaseState(false, 101)).toJSONString();
        }
    }

}

其中case 4中的Uploader需要重寫

2.重寫Uploader

import com.baidu.ueditor.define.State;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * Created by GustinLau on 2017-05-11.
 */
public class Uploader {
    private HttpServletRequest request = null;
    private Map<String, Object> conf = null;

    public Uploader(HttpServletRequest request, Map<String, Object> conf) {
        this.request = request;
        this.conf = conf;
    }

    public final State doExec() {
        String filedName = (String) this.conf.get("fieldName");
        State state;
        if ("true".equals(this.conf.get("isBase64"))) {
            state = Base64Uploader.save(this.request.getParameter(filedName), this.conf);
        } else {
            state = BinaryUploader.save(this.request, this.conf);
        }

        return state;
    }
}

其中Base64UploaderBinaryUploader需要重寫

3.重寫Base64Uploader,主要用于涂鴉功能

import com.baidu.ueditor.PathFormat;
import com.baidu.ueditor.define.BaseState;
import com.baidu.ueditor.define.FileType;
import com.baidu.ueditor.define.State;
import com.xiaosuokeji.feelschool.admin.util.OssUtils;
import org.apache.commons.codec.binary.Base64;

import java.io.ByteArrayInputStream;
import java.util.Map;

/**
 * Created by GustinLau on 2017-05-11.
 */
public class Base64Uploader {

    public static State save(String content, Map<String, Object> conf) {
        byte[] data = decode(content);
        long maxSize = ((Long) conf.get("maxSize")).longValue();
        if (!validSize(data, maxSize)) {
            return new BaseState(false, 1);
        } else {
            String suffix = FileType.getSuffix("JPG");
            String savePath = PathFormat.parse((String) conf.get("savePath"), (String) conf.get("filename"));
            savePath = savePath + suffix;
            
            //自定義處理部分
            //將byte[]轉換成輸入流
            ByteArrayInputStream is = new ByteArrayInputStream(data);
            //圖片上傳到阿里云OSS服務器,自己寫的工具類
            Map result = OssUtils.ueditorUpload(is, savePath);
            //構造對應的Stage讓UEditor讀取
            State storageState = new BaseState((boolean) result.get("status"));
            if (storageState.isSuccess()) {
                storageState.putInfo("url", (String) result.get("url"));
                storageState.putInfo("type", suffix);
                storageState.putInfo("original", "");
            }

            return storageState;
        }
    }

    private static byte[] decode(String content) {
        return Base64.decodeBase64(content);
    }

    private static boolean validSize(byte[] data, long length) {
        return (long) data.length <= length;
    }
}

4.重寫BinaryUploader主要用于上傳圖片

import com.baidu.ueditor.PathFormat;
import com.baidu.ueditor.define.BaseState;
import com.baidu.ueditor.define.FileType;
import com.baidu.ueditor.define.State;
import com.xiaosuokeji.feelschool.admin.util.OssUtils;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * Created by GustinLau on 2017-05-11.
 */
public class BinaryUploader {

    public static final State save(HttpServletRequest request, Map<String, Object> conf) {
        MultipartFile multipartFile = null;
        boolean isAjaxUpload = request.getHeader("X_Requested_With") != null;
        if (!ServletFileUpload.isMultipartContent(request)) {
            return new BaseState(false, 5);
        } else {
            ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory());
            if (isAjaxUpload) {
                upload.setHeaderEncoding("UTF-8");
            }
            //自定義處理部分
            try {
                //request獲取MultipartFile對象
                MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
                multipartFile = multipartRequest.getFile(conf.get("fieldName").toString());

                if (multipartFile == null) {
                    return new BaseState(false, 7);
                } else {
                    //重命名
                    String savePath = (String) conf.get("savePath");
                    String originFileName = multipartFile.getOriginalFilename();
                    String suffix = FileType.getSuffixByFilename(originFileName);
                    originFileName = originFileName.substring(0, originFileName.length() - suffix.length());
                    savePath = savePath + suffix;
                    if (!validType(suffix, (String[]) conf.get("allowFiles"))) {
                        return new BaseState(false, 8);
                    } else {
                        savePath = PathFormat.parse(savePath, originFileName);
                        //獲取輸入流
                        InputStream is = multipartFile.getInputStream();
                        //上傳到阿里云OSS
                        Map result = OssUtils.ueditorUpload(is, savePath);
                        //構造State
                        State storageState = new BaseState((boolean) result.get("status"));
                        is.close();
                        if (storageState.isSuccess()) {
                            storageState.putInfo("url", (String) result.get("url"));
                            storageState.putInfo("type", suffix);
                            storageState.putInfo("original", originFileName + suffix);
                        }

                        return storageState;
                    }
                }
            } catch (IOException e) {
                return new BaseState(false, 4);
            }
        }
    }

    private static boolean validType(String type, String[] allowTypes) {
        List<String> list = Arrays.asList(allowTypes);
        return list.contains(type);
    }
}

5.將在WEB-INF/assets/plugins/ueditor/jsp/controller.jsp中的ActionEnter換自己重寫的ActionEnter

依賴

<!--ueditor-->
<dependency>
    <groupId>com.baidu</groupId>
    <artifactId>ueditor</artifactId>
    <version>1.1.2</version>
    <scope>system</scope>
    <systemPath>${project.basedir}/lib/ueditor-1.1.2.jar</systemPath>
</dependency>
<!--json-->
<dependency>
    <groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <version>20160212</version>
</dependency>

 <dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.10</version>
</dependency>
<!--fileupload-->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.4</version>
</dependency>
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.1</version>
</dependency>

備注

記得在spring.xml中配置MultipartResolver

<!-- 配置MultipartResolver 用于文件上傳 使用spring的CommonsMultipartResolver -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="defaultEncoding" value="UTF-8"/>
    <property name="maxUploadSize" value="${file.maxSize}"/>
    <property name="resolveLazily" value="true"/>
</bean>
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,460評論 6 538
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,067評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,467評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,468評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,184評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,582評論 1 325
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,616評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,794評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,343評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,096評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,291評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,863評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,513評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,941評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,190評論 1 291
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,026評論 3 396
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,253評論 2 375

推薦閱讀更多精彩內容