百度ueditor富文本編輯器實現上傳文件、圖片、視頻到ftp服務器並在頁面端回顯


之前一直用ueditor作為富文本編輯器,想要實現圖片上傳到ftp的功能,網上搜索了一圈,發現都感覺講的不是很明白,而且有不少要引入其他的java代碼,最近自己試了一下,終於調通了,希望能幫到各位。廢話不多說,查看步驟。(注意,這個是springboot版本,其實springmvc的也差不多,有一點點不同,最后我會說明)

  1.將utf8-jsp的整個文件夾復制到resources的static目錄下,打開之后目錄如下。


項目目錄如下(我多加了一層ueditor目錄,不過也一樣)

 


 

2.寫兩個controller,代碼如下(請忽略樓主潦草的代碼,自己拿回去調整一下,修改一下UploadController中ftp的地址,密碼即可,總共有三個地方)

1.UploadController

  

package com.wang.controller;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPConnectionClosedException;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;

@RequestMapping("/ueditor/file")
@Controller
@Slf4j
public class UploadController {

    private FTPClient ftpClient = new FTPClient();
    private Logger logger = LoggerFactory.getLogger(UploadController.class);

    //上傳圖片並回顯
    @RequestMapping("/uploadImg")
    @ResponseBody
    public Map<String,Object> upload(HttpServletRequest request) throws Exception {
        Map<String ,Object> map = new HashMap<>();
        // 判斷enctype屬性是否為multipart/form-data
        boolean isMultipart = ServletFileUpload.isMultipartContent(request);
        if (!isMultipart)
            throw new IllegalArgumentException(
                    "上傳內容不是有效的multipart/form-data類型.");

        // Create a factory for disk-based file items
        DiskFileItemFactory factory = new DiskFileItemFactory();

        // Create a new file upload handler
        ServletFileUpload upload = new ServletFileUpload(factory);

        // Parse the request
        List<FileItem> items = upload.parseRequest(request);

        Iterator iter = items.iterator();
        while (iter.hasNext()) {
            FileItem item = (FileItem) iter.next();
                // 如果是文件字段
                String fieldName = item.getFieldName();
                String orginFileName = item.getName();
                String imgSunffix = orginFileName.substring(orginFileName.lastIndexOf("."));
                String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                String fileName = uuid+imgSunffix;
//                String contentType = item.getContentType();
//                boolean isInMemory = item.isInMemory();
//                long sizeInBytes = item.getSize();

//                String filePath = STORE_FILE_DIR + fileName;
                //寫入文件到當前服務器磁盤
//                File uploadedFile = new File(filePath);

                SimpleDateFormat formatPath = new SimpleDateFormat("yyMMdd");
                SimpleDateFormat fromahhPath = new SimpleDateFormat("HH");
                String yyMMdd =  formatPath.format(new Date());
                String hours = fromahhPath.format(new Date());
                String ftpfilePath = yyMMdd + "/" + hours;

//                FileInputStream fileInputStream = (FileInputStream) item.getInputStream();
                InputStream inputStream = item.getInputStream();

                BufferedInputStream bufferedInputStream = null;
                bufferedInputStream = new BufferedInputStream(inputStream);
                FTPClient ftp = new FTPClient();
                try {
                    int reply;
                    ftp.connect("11111", 21);// 連接FTP服務器
                    // 如果采用默認端口,可以使用ftp.connect(url)的方式直接連接FTP服務器
                    ftp.login("11111", "11111");// 登錄
                    ftp.setFileType(FTP.BINARY_FILE_TYPE);
                    ftp.setFileTransferMode(FTP.STREAM_TRANSFER_MODE);
                    reply = ftp.getReplyCode();
                    if(!FTPReply.isPositiveCompletion(reply)){
                        ftp.disconnect();
                        throw new IOException("ftp登錄失敗");
                    }
                    for (String str:ftpfilePath.split("/")){
                        ftp.makeDirectory(str);
                        ftp.changeWorkingDirectory(str);
                    }
                    boolean tag = ftp.appendFile(fileName,bufferedInputStream);
                    if(!tag){
                        throw new Exception("保存到FTP失敗");
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }finally {
                    try {
                        inputStream.close();
                        ftp.logout();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    if(ftp.isConnected()){
                        try {
                            ftp.disconnect();
                        }catch (IOException e){
                            e.printStackTrace();
                        }
                    }
                }
                String path = "/"+ftpfilePath+"/"+fileName;

//                item.write(uploadedFile);
                map.put("state","SUCCESS");
                map.put("url",path);
                map.put("title",orginFileName);
                map.put("original",orginFileName);
        }
//        response.setCharacterEncoding("UTF-8");
//        response.getWriter().println("上傳成功");
        return map;
    }

    //回顯圖片

    @RequestMapping("/getImg.do")
    @ResponseBody
    public void getImg( HttpServletResponse response,@RequestParam("path")String imgPath) {
        FTPClient ftp = null;
        InputStream in = null;
//        imgPath = "ftpfile\\upload\\11.png";
        OutputStream os = null;
        ftp = new FTPClient();
        ftp.setConnectTimeout(1000 * 30);//設置連接超時時間
        ftp.setControlEncoding("utf-8");//設置ftp字符集
        ftp.enterLocalPassiveMode();//設置被動模式,文件傳輸端口設置
        try {
            int reply;
            ftp.connect("11111", 21);// 連接FTP服務器
            // 如果采用默認端口,可以使用ftp.connect(url)的方式直接連接FTP服務器
            ftp.login("11111", "11111");// 登錄
            ftp.setFileType(FTP.BINARY_FILE_TYPE);
            ftp.setFileTransferMode(FTP.STREAM_TRANSFER_MODE);
            reply = ftp.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftp.disconnect();
                throw new IOException("FTP登錄失敗");
            }
            //下載文件 FTP協議里面,規定文件名編碼為iso-8859-1,所以讀取時要將文件名轉碼為iso-8859-1
            //如果沒有設置按照UTF-8讀,獲取的流是空值null
            in = ftp.retrieveFileStream(new String(imgPath.getBytes("UTF-8"), "iso-8859-1"));
            String picType = imgPath.split("\\.")[1];

            BufferedImage bufImg = null;
            bufImg = ImageIO.read(in);
            os = response.getOutputStream();
            ImageIO.write(bufImg, picType, os);

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                in.close();// 在這里關閉,保證一定要關閉
                ftp.logout();// 在這里登出,保證一定要登出
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
        response.setContentType("image/jpg");
    }


    /**
     * 下載文件到瀏覽器
     * @param response
     * @throws IOException
     */
    @RequestMapping("/downloadFile.do")
    @ResponseBody
    public  void downFile(@RequestParam("path")String path, HttpServletResponse response) throws IOException {
// 獲取ftp信息

        // 獲取文件名稱
        String[] strs = path.split("/");
        String downloadFile = strs[strs.length - 1];
        try {
            // 設置文件ContentType類型,這樣設置,會自動判斷下載文件類型
            response.setContentType("application/x-msdownload");
            // 設置文件頭:最后一個參數是設置下載的文件名並編碼為UTF-8
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(downloadFile, "UTF-8"));
            // 建立連接
            connectToServer();

            ftpClient.enterLocalPassiveMode();
            // 設置傳輸二進制文件
            int reply = ftpClient.getReplyCode();
//            ftpClient.changeWorkingDirectory("./home/ftp");
            if(!FTPReply.isPositiveCompletion(reply)) {
                ftpClient.disconnect();
                throw new IOException("failed to connect to the FTP Server:"+21);
            }
            // 此句代碼適用Linux的FTP服務器
            String newPath = new String(path.getBytes("GBK"),"ISO-8859-1");
            // ftp文件獲取文件
            InputStream is = null;
            BufferedInputStream bis = null;
            try {
                is = ftpClient.retrieveFileStream(newPath);
                bis = new BufferedInputStream(is);
                OutputStream out = response.getOutputStream();
                byte[] buf = new byte[1024];
                int len = 0;
                while ((len = bis.read(buf)) > 0) {
                    out.write(buf, 0, len);
                }
                out.flush();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                closeConnect();
                if (bis != null) {
                    try {
                        bis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (is != null) {
                    try {
                        is.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        } catch (FTPConnectionClosedException e) {
            logger.error("ftp連接被關閉!", e);
            throw e;
        } catch (Exception e) {
            logger.error("ERR : upload file "+ downloadFile+ " from ftp : failed!", e);
        }

    }

    /**
     * 連接到ftp服務器
     */
    private void connectToServer() throws Exception {

//        ftpClient.connect(server,21);
        if (!ftpClient.isConnected()) {
            int reply;
            try {
                ftpClient=new FTPClient();
                ftpClient.connect("111111", 21);// 連接FTP服務器
                // 如果采用默認端口,可以使用ftp.connect(url)的方式直接連接FTP服務器
                ftpClient.login("111111", "111111");// 登錄
                reply = ftpClient.getReplyCode();

                if (!FTPReply.isPositiveCompletion(reply)) {
                    ftpClient.disconnect();
                    logger.info("connectToServer FTP server refused connection.");
                }

            }catch(FTPConnectionClosedException ex){
                logger.error("服務器:IP:"+21+"沒有連接數!there are too many connected users,please try later", ex);
                throw ex;
            }catch (Exception e) {
                logger.error("登錄ftp服務器【"+21+"】失敗", e);
                throw e;
            }
        }
    }

    /**
     *
     * 功能:關閉連接
     */
    public void closeConnect() {
        try {
            if (ftpClient != null) {
                ftpClient.logout();
                ftpClient.disconnect();
            }
        } catch (Exception e) {
            logger.error("ftp連接關閉失敗!", e);
        }
    }


}

  2.ServerController

  

package com.wang.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baidu.ueditor.ActionEnter;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Controller;
import org.springframework.util.ClassUtils;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;

//ueditor單獨上傳的controller
@Controller
public class ServerController {
    @RequestMapping("/configNew")
    public void config(HttpServletRequest request, HttpServletResponse response){
        response.setContentType("application/json");
//        String res = ClassUtils.getDefaultClassLoader().getResource("km").getPath();
//        System.out.println("res:"+res);
        System.out.println("路徑:"+ClassUtils.getDefaultClassLoader().getResource("").getPath());
//        String rootPath = ClassUtils.getDefaultClassLoader().getResource("../../").getPath() + "static/ueditor/jsp";
        String rootPath = ClassUtils.getDefaultClassLoader().getResource("").getPath() + "static/ueditor/jsp";
        System.out.println("root路徑:"+rootPath);
        try {
            response.setCharacterEncoding("UTF-8");
            String exec = new ActionEnter(request, rootPath).exec();
            System.out.println(exec);
            PrintWriter writer = response.getWriter();
            writer.write(new ActionEnter(request, rootPath).exec());
            writer.flush();
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


//    public void getUEConfig(HttpServletRequest request, HttpServletResponse response){
//        org.springframework.core.io.Resource res = new ClassPathResource("config.json");
//        InputStream is = null;
//        response.setHeader("Content-Type" , "text/html");
//        try {
//            is = new FileInputStream(res.getFile());
//            StringBuffer sb = new StringBuffer();
//            byte[] b = new byte[1024];
//            int length=0;
//            while(-1!=(length=is.read(b))){
//                sb.append(new String(b,0,length,"utf-8"));
//            }
//            String result = sb.toString().replaceAll("/\\*(.|[\\r\\n])*?\\*/","");
//            JSONObject json = JSON.parseObject(result);
//            PrintWriter out = response.getWriter();
//            out.print(json.toString());
//        } catch (IOException e) {
//            e.printStackTrace();
//        }finally {
//            try {
//                is.close();
//            } catch (IOException e) {
//                e.printStackTrace();
//            }
//        }
//    }

}

 3.修改ueditor.config.js

   

 

 

   

var URL = window.UEDITOR_HOME_URL || getUEBasePath();
    var server_url = window.location.protocol+"//"+window.location.hostname+":"+window.location.port;

    /**
     * 配置項主體。注意,此處所有涉及到路徑的配置別遺漏URL變量。
     */
    window.UEDITOR_CONFIG = {

        //為編輯器實例添加一個路徑,這個不能被注釋
        UEDITOR_HOME_URL: URL

        // 服務器統一請求接口路徑
        // , serverUrl: URL + "jsp/controller.jsp"
        , serverUrl: server_url+"/configNew"

 

 

 

 

 4.修改ueditor的jsp目錄下的config.json文件 目錄圖片如下

 

 

    打開這個文件之后修改大概7.8個地方的參數,都是xxxUrlPrefix,反正只要是圖片注釋就換成Ueditortxtcontroller中的getIMg路徑,文件就換成downloadFile路徑

 

  圖片

 

 

   文件路徑

  

 

  5.關鍵一步,記得在你的啟動類application中排除掉有關文件上傳的自動配置。

  

 

 

 如果是springmvc,那就是在xml文件中注釋掉multipartfile這個bean了

 

 

 

 6.然后是改造的你的編輯器的訪問頁面index.html。

  

 

 

 在ue.ready方法中換掉相關原有的訪問路徑即可

 

 

 這是樓主的html頁面,如果要用的話,記得把那個juqery-3.5.1.min.js和一個保存saveContent的方法排除掉就可以了

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <title>完整demo</title>
    <link REL="shortcut icon" href="/favicon.ico" type="image/ico"/>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
    <script type="text/javascript" charset="utf-8" src="/ueditor/ueditor.config.js"></script>
    <script type="text/javascript" charset="utf-8" src="/ueditor/ueditor.all.min.js"> </script>
    <script type="text/javascript" charset="utf-8" src="/js/jquery-3.5.1.min.js"> </script>
    <!--建議手動加在語言,避免在ie下有時因為加載語言失敗導致編輯器加載失敗-->
    <!--這里加載的語言文件會覆蓋你在配置項目里添加的語言類型,比如你在配置項目里配置的是英文,這里加載的中文,那最后就是中文-->
    <script type="text/javascript" charset="utf-8" src="/ueditor/lang/zh-cn/zh-cn.js"></script>

    <style type="text/css">
        div{
            width:100%;
        }
    </style>
</head>
<body>
<div>
    <h1>完整demo</h1>
    <script id="editor" type="text/plain" style="width:1024px;height:500px;"></script>
</div>
<div id="btns">
    <div>
        <button onclick="saveContent()">保存</button>
        <button onclick="getAllHtml()">獲得整個html的內容</button>
        <button onclick="getContent()">獲得內容</button>
        <button onclick="setContent()">寫入內容</button>
        <button onclick="setContent(true)">追加內容</button>
        <button onclick="getContentTxt()">獲得純文本</button>
        <button onclick="getPlainTxt()">獲得帶格式的純文本</button>
        <button onclick="hasContent()">判斷是否有內容</button>
        <button onclick="setFocus()">使編輯器獲得焦點</button>
        <button onmousedown="isFocus(event)">編輯器是否獲得焦點</button>
        <button onmousedown="setblur(event)" >編輯器失去焦點</button>

    </div>
    <div>
        <button onclick="getText()">獲得當前選中的文本</button>
        <button onclick="insertHtml()">插入給定的內容</button>
        <button id="enable" onclick="setEnabled()">可以編輯</button>
        <button onclick="setDisabled()">不可編輯</button>
        <button onclick=" UE.getEditor('editor').setHide()">隱藏編輯器</button>
        <button onclick=" UE.getEditor('editor').setShow()">顯示編輯器</button>
        <button onclick=" UE.getEditor('editor').setHeight(300)">設置高度為300默認關閉了自動長高</button>
    </div>

    <div>
        <button onclick="getLocalData()" >獲取草稿箱內容</button>
        <button onclick="clearLocalData()" >清空草稿箱</button>
    </div>

</div>
<div>
    <button onclick="createEditor()">
    創建編輯器</button>
    <button onclick="deleteEditor()">
    刪除編輯器</button>
</div>

<script type="text/javascript">

    //實例化編輯器
    //建議使用工廠方法getEditor創建和引用編輯器實例,如果在某個閉包下引用該編輯器,直接調用UE.getEditor('editor')就能拿到相關的實例
    var ue = UE.getEditor('editor');

    ue.ready(function () {
        UE.Editor.prototype._bkGetActionUrl=UE.Editor.prototype.getActionUrl;
        UE.Editor.prototype.getActionUrl=function(action){
            if (action == 'uploadimage' ||action== 'uploadscrawl' || action == 'uploadimage') {
                return "/ueditor/file/uploadImg";
            } else if(action =='uploadvideo') {
                return "/ueditor/file/uploadImg";
            } else if(action == 'listimage'){
                return "/ueditor/file/uploadImg";
            } else if(action == 'uploadfile'){
                return "/ueditor/file/uploadImg";
            } else{
                return this._bkGetActionUrl.call(this, action);
            }
        }
    });
    function isFocus(e){
        alert(UE.getEditor('editor').isFocus());
        UE.dom.domUtils.preventDefault(e)
    }
    function setblur(e){
        UE.getEditor('editor').blur();
        UE.dom.domUtils.preventDefault(e)
    }
    function insertHtml() {
        var value = prompt('插入html代碼', '');
        UE.getEditor('editor').execCommand('insertHtml', value)
    }
    function createEditor() {
        enableBtn();
        UE.getEditor('editor');
    }
    function getAllHtml() {
        alert(UE.getEditor('editor').getAllHtml())
    }
    function saveContent() {
        var arr = [];
        arr.push(UE.getEditor('editor').getContent());
        $.ajax({
            type : 'post',
            dataType : 'json',
            url : '/ueditortxt/save',
            data:{
                content: arr.join("\n")
            },
            success:function(datas){
                alert("添加成功");
            },
            error:function(a,b,c){
                alert("添加失敗");
            }
        });
    }
    function getContent() {
        var arr = [];
        arr.push("使用editor.getContent()方法可以獲得編輯器的內容");
        arr.push("內容為:");
        arr.push(UE.getEditor('editor').getContent());
        alert(arr.join("\n"));
    }
    function getPlainTxt() {
        var arr = [];
        arr.push("使用editor.getPlainTxt()方法可以獲得編輯器的帶格式的純文本內容");
        arr.push("內容為:");
        arr.push(UE.getEditor('editor').getPlainTxt());
        alert(arr.join('\n'))
    }
    function setContent(isAppendTo) {
        var arr = [];
        arr.push("使用editor.setContent('歡迎使用ueditor')方法可以設置編輯器的內容");
        UE.getEditor('editor').setContent('歡迎使用ueditor', isAppendTo);
        alert(arr.join("\n"));
    }
    function setDisabled() {
        UE.getEditor('editor').setDisabled('fullscreen');
        disableBtn("enable");
    }

    function setEnabled() {
        UE.getEditor('editor').setEnabled();
        enableBtn();
    }

    function getText() {
        //當你點擊按鈕時編輯區域已經失去了焦點,如果直接用getText將不會得到內容,所以要在選回來,然后取得內容
        var range = UE.getEditor('editor').selection.getRange();
        range.select();
        var txt = UE.getEditor('editor').selection.getText();
        alert(txt)
    }

    function getContentTxt() {
        var arr = [];
        arr.push("使用editor.getContentTxt()方法可以獲得編輯器的純文本內容");
        arr.push("編輯器的純文本內容為:");
        arr.push(UE.getEditor('editor').getContentTxt());
        alert(arr.join("\n"));
    }
    function hasContent() {
        var arr = [];
        arr.push("使用editor.hasContents()方法判斷編輯器里是否有內容");
        arr.push("判斷結果為:");
        arr.push(UE.getEditor('editor').hasContents());
        alert(arr.join("\n"));
    }
    function setFocus() {
        UE.getEditor('editor').focus();
    }
    function deleteEditor() {
        disableBtn();
        UE.getEditor('editor').destroy();
    }
    function disableBtn(str) {
        var div = document.getElementById('btns');
        var btns = UE.dom.domUtils.getElementsByTagName(div, "button");
        for (var i = 0, btn; btn = btns[i++];) {
            if (btn.id == str) {
                UE.dom.domUtils.removeAttributes(btn, ["disabled"]);
            } else {
                btn.setAttribute("disabled", "true");
            }
        }
    }
    function enableBtn() {
        var div = document.getElementById('btns');
        var btns = UE.dom.domUtils.getElementsByTagName(div, "button");
        for (var i = 0, btn; btn = btns[i++];) {
            UE.dom.domUtils.removeAttributes(btn, ["disabled"]);
        }
    }

    function getLocalData () {
        alert(UE.getEditor('editor').execCommand( "getlocaldata" ));
    }

    function clearLocalData () {
        UE.getEditor('editor').execCommand( "clearlocaldata" );
        alert("已清空草稿箱")
    }
</script>
</body>
</html>

  

7.現在就可以訪問這個頁面然后上傳文件、圖片、視頻並且回顯了

  文件

 

 

 效果

 

 

 圖片

 

 

 效果:

 

 

 

視頻:

 

 

 效果:

 

 

 

這里有個問題,就是如果連續點擊這個按鈕,頁面會回顯不了視頻,我發現可以把那個Ueditor的XSS過濾關掉就可以(注意,這個操作我也不知道會導致什么問題,慎重操作)

 

 

 

關掉XSS過濾,修改ueditor.config.js中的三個參數為false即可

 

 

 

 

至此就完成了,如果是springmvc的話怎么辦呢?

三步不同

1.將serverController中上半部分代碼注釋掉,放開下半部分中注釋掉的代碼

2.將改造過后的config.json文件放到resource下面

3.pom文件中放開對json文件的限制,以便target中能夠找到該文件

 項目地址:https://gitee.com/wl173/ueditorupload.git  看readme就行了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM