天天看點

Spring Boot內建Ueditor富文本編輯器,實作圖檔上傳,視訊上傳,傳回内容功能并且通過OSS轉換為連結并且解決Spring Security靜态資源通路以及跨域問題

學習自https://cloud.tencent.com/developer/article/1452451

現在是晚上22點,剛剛和我們的前端交流完了富文本編輯器的一些意見和看法

還是老樣子

需求

我們的團隊官網需要不定期釋出團隊視訊,團隊風采以及團隊獲獎情況等,第一版的時候,我的資料庫還是以普通的文本模式做的,比如視訊url,圖檔url都有,但是前端已經使用富文本編輯器進行整體的儲存,這樣我的一些屬性就處于沒有用的狀态,同時這樣做,那些屬性卻依舊需要修改,他特别是更改頭像和視訊的時候,這就太麻煩和重複了。另外,前端應該也不是太會,當時是整體,連同資源本身傳過來的,我甚至隻能用longtext來存儲,這樣查詢的時候也是特别的慢.另外當時的資源也是存儲在伺服器上,而且不是網絡資源,需要首先讀取,這樣在播放和swagger文檔查詢的時候就非常緩慢了。是以現在準備重做第二版,實作的方案也優化一下,選擇富文本編輯器以及阿裡雲OSS共同實作。

實作

  • 下載下傳連結

    我選擇的是Ueditor,因為比較好(主要是大家都在用),但是第一版的時候前端他們用的是wangeditor。這裡先不管了

    官網連結:

    ​​​ueditor​​​ 選擇最新版(已經停止更新了)jSP+UTF-8

    下載下傳解壓效果圖,檔案名

  • Spring Boot內建Ueditor富文本編輯器,實作圖檔上傳,視訊上傳,傳回内容功能并且通過OSS轉換為連結并且解決Spring Security靜态資源通路以及跨域問題
  • 這個時候用浏覽器打開index.html應該可以看到效果
  • Spring Boot內建Ueditor富文本編輯器,實作圖檔上傳,視訊上傳,傳回内容功能并且通過OSS轉換為連結并且解決Spring Security靜态資源通路以及跨域問題
  • 內建到Spring Boot項目中

    我是直接把檔案複制到resource檔案夾之中

  • Spring Boot內建Ueditor富文本編輯器,實作圖檔上傳,視訊上傳,傳回内容功能并且通過OSS轉換為連結并且解決Spring Security靜态資源通路以及跨域問題
  • 同時把index.html放到templates中

網上一般的教程,隻要導入到項目中,然後運作就可以看到首頁的内容

但是我內建了Spring Security Oauth2以及發現缺少Ueditor依賴是以還要做很多東西

  • 內建Ueditor依賴
<!--Ueditor依賴的jar包-->
        <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
            <version>20190722</version>
        </dependency>
        <dependency>
            <groupId>com.gitee.qdbp.thirdparty</groupId>
            <artifactId>ueditor</artifactId>
            <version>1.4.3.3</version>
        </dependency>
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.9</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.4</version>
        </dependency>      

其中Ueditor依賴因為官放沒有內建,使用的是一個私人的把

其他commons開頭的關于檔案的盡量與jar/lib的版本保持一緻

  • 解決Spring Security 靜态資源拒絕通路問題
  1. 首先配置忽略資源通路限制
//開啟全局方法驗證
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class GlobalMethodSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/static/**");
    }

}      

因為我這是一個oss的資源伺服器,是以建立一個Security配置類

2. 然後設定資源映射

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    /**
     * 配置靜态資源
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
        //super.addResourceHandlers(registry);
    }
}      
  • 設定全局跨域許可

    我設定完靜态資源後,依舊顯示401,這讓我就結了很久,最後發現是跨域問題

@Configuration
public class CorsConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addCorsMappings(CorsRegistry registry) {

        registry.addMapping("/**")
                .allowCredentials(true)
                .allowedHeaders("*")
                .allowedOrigins("*")
                .allowedMethods("*");


}}      
  • 解決控制台報錯

    Refused to display ‘http://localhost/xxxx’ in a frame because it…

.headers().frameOptions().disable();      
  • 運作程式已經能夠正常通路

    但是上傳檔案顯示

  • Spring Boot內建Ueditor富文本編輯器,實作圖檔上傳,視訊上傳,傳回内容功能并且通過OSS轉換為連結并且解決Spring Security靜态資源通路以及跨域問題
  • ​​這張圖我是直接拿了别人的​​

開始解決檔案上傳問題

  1. 建立Ueditor對象
package cn.hcnet2006.blog.hcnetwebsite.ueditor;

public class Ueditor {
    private  String state;
    private  String url;
    private  String title;
    private  String original;

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getOriginal() {
        return original;
    }

    public void setOriginal(String original) {
        this.original = original;
    }
}      
  1. 建立PublicMsg類,替代config.json
package cn.hcnet2006.blog.hcnetwebsite.ueditor;

public class PublicMsg {
    public final static String UEDITOR_CONFIG = "{\n" +
            "    \"imageActionName\": \"uploadimage\",\n" +
            "    \"imageFieldName\": \"upfile\",\n" +
            "    \"imageMaxSize\": 2048000,\n" +
            "    \"imageAllowFiles\": [\".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\"],\n" +
            "    \"imageCompressEnable\": true,\n" +
            "    \"imageCompressBorder\": 1600,\n" +
            "    \"imageInsertAlign\": \"none\",\n" +
            "    \"imageUrlPrefix\": \"\",\n" +
            "    \"imagePathFormat\": \"/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}\",\n" +
            "\n" +
            "    \"scrawlActionName\": \"uploadscrawl\",\n" +
            "    \"scrawlFieldName\": \"upfile\",\n" +
            "    \"scrawlPathFormat\": \"/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}\",\n" +
            "    \"scrawlMaxSize\": 2048000,\n" +
            "    \"scrawlUrlPrefix\": \"\",\n" +
            "    \"scrawlInsertAlign\": \"none\",\n" +
            "\n" +
            "    \"snapscreenActionName\": \"uploadimage\",\n" +
            "    \"snapscreenPathFormat\": \"/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}\",\n" +
            "    \"snapscreenUrlPrefix\": \"\",\n" +
            "    \"snapscreenInsertAlign\": \"none\",\n" +
            "\n" +
            "    \"catcherLocalDomain\": [\"127.0.0.1\", \"localhost\", \"img.baidu.com\"],\n" +
            "    \"catcherActionName\": \"catchimage\",\n" +
            "    \"catcherFieldName\": \"source\",\n" +
            "    \"catcherPathFormat\": \"/ueditor/jsp/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}\",\n" +
            "    \"catcherUrlPrefix\": \"\",\n" +
            "    \"catcherMaxSize\": 2048000,\n" +
            "    \"catcherAllowFiles\": [\".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\"],\n" +
            "\n" +
            "    \"videoActionName\": \"uploadvideo\",\n" +
            "    \"videoFieldName\": \"upfile\",\n" +
            "    \"videoPathFormat\": \"/ueditor/jsp/upload/video/{yyyy}{mm}{dd}/{time}{rand:6}\",\n" +
            "    \"videoUrlPrefix\": \"\",\n" +
            "    \"videoMaxSize\": 102400000,\n" +
            "    \"videoAllowFiles\": [\n" +
            "        \".flv\", \".swf\", \".mkv\", \".avi\", \".rm\", \".rmvb\", \".mpeg\", \".mpg\",\n" +
            "        \".ogg\", \".ogv\", \".mov\", \".wmv\", \".mp4\", \".webm\", \".mp3\", \".wav\", \".mid\"],\n" +
            "\n" +
            "    \"fileActionName\": \"uploadfile\",\n" +
            "    \"fileFieldName\": \"upfile\",\n" +
            "    \"filePathFormat\": \"/ueditor/jsp/upload/file/{yyyy}{mm}{dd}/{time}{rand:6}\",\n" +
            "    \"fileUrlPrefix\": \"\",\n" +
            "    \"fileMaxSize\": 51200000,\n" +
            "    \"fileAllowFiles\": [\n" +
            "        \".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\",\n" +
            "        \".flv\", \".swf\", \".mkv\", \".avi\", \".rm\", \".rmvb\", \".mpeg\", \".mpg\",\n" +
            "        \".ogg\", \".ogv\", \".mov\", \".wmv\", \".mp4\", \".webm\", \".mp3\", \".wav\", \".mid\",\n" +
            "        \".rar\", \".zip\", \".tar\", \".gz\", \".7z\", \".bz2\", \".cab\", \".iso\",\n" +
            "        \".doc\", \".docx\", \".xls\", \".xlsx\", \".ppt\", \".pptx\", \".pdf\", \".txt\", \".md\", \".xml\"\n" +
            "    ],\n" +
            "\n" +
            "    \"imageManagerActionName\": \"listimage\",\n" +
            "    \"imageManagerListPath\": \"/ueditor/jsp/upload/image/\",\n" +
            "    \"imageManagerListSize\": 20,\n" +
            "    \"imageManagerUrlPrefix\": \"\",\n" +
            "    \"imageManagerInsertAlign\": \"none\",\n" +
            "    \"imageManagerAllowFiles\": [\".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\"],\n" +
            "\n" +
            "    \"fileManagerActionName\": \"listfile\",\n" +
            "    \"fileManagerListPath\": \"/ueditor/jsp/upload/file/\",\n" +
            "    \"fileManagerUrlPrefix\": \"\",\n" +
            "    \"fileManagerListSize\": 20,\n" +
            "    \"fileManagerAllowFiles\": [\n" +
            "        \".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\",\n" +
            "        \".flv\", \".swf\", \".mkv\", \".avi\", \".rm\", \".rmvb\", \".mpeg\", \".mpg\",\n" +
            "        \".ogg\", \".ogv\", \".mov\", \".wmv\", \".mp4\", \".webm\", \".mp3\", \".wav\", \".mid\",\n" +
            "        \".rar\", \".zip\", \".tar\", \".gz\", \".7z\", \".bz2\", \".cab\", \".iso\",\n" +
            "        \".doc\", \".docx\", \".xls\", \".xlsx\", \".ppt\", \".pptx\", \".pdf\", \".txt\", \".md\", \".xml\"\n" +
            "    ] \n" +
            "\n" +
            "}";
    /**
     * Ueditor的傳回狀态類型
     */
    public enum UeditorMsg{
        SUCCESS("SUCCESS"),ERROR("上傳失敗");
        private String v;
        UeditorMsg(String v){
            this.v =v;
        }
        public String get(){
            return this.v;
        }
    }
}      
  1. 在UeditorController上添加獲得上傳圖檔的方法
{
    @RequestMapping("/")
    private String showPage(){
        return "index";
    }

    @RequestMapping(value="/ueditor")
    @ResponseBody
    public String ueditor(HttpServletRequest request) {

        return PublicMsg.UEDITOR_CONFIG;
    }

    @RequestMapping(value="/imgUpload")
    @ResponseBody
    public Map<String, Object> images (MultipartFile upfile, HttpServletRequest request, HttpServletResponse response){
        Map<String, Object> params = new HashMap<String, Object>();
        System.out.println("1111111111111");
        try{
            String url = ResourceUtils.getURL("").getPath()+upfile.getOriginalFilename();
            File folder = new File(url);
            upfile.transferTo(folder);
            url = OSSUtils.upload(folder, UUID.randomUUID().toString()+upfile.getOriginalFilename().substring(upfile.getOriginalFilename().lastIndexOf(".")));
            System.out.println(UUID.randomUUID().toString()+upfile.getOriginalFilename().substring(upfile.getOriginalFilename().lastIndexOf(".")));
            folder.delete();
            String fileName = upfile.getOriginalFilename();
            params.put("state", "SUCCESS");
            params.put("url", url);
            params.put("size", upfile.getSize());
            params.put("original", fileName);
            params.put("type", upfile.getContentType());

        } catch (Exception e){
            params.put("state", "ERROR");
        }
        return params;
    }

}      

​​https://cloud.tencent.com/developer/article/1452451​​ 自己摸索了一下:

.UEDITOR_CONFIG = {

        //為編輯器執行個體添加一個路徑,這個不能被注釋
        UEDITOR_HOME_URL: URL
        // 伺服器統一請求接口路徑
        //, serverUrl: URL + "jsp/controller.jsp"
    , serverUrl: "/ueditor"      
  1. 配置Ueditor.config.js

    這裡有一個坑,不是這樣

将:
, serverUrl: URL + "jsp/controller.jsp"
替換為:
, serverUrl: "/ueditor"      

而是這樣

// 伺服器統一請求接口路徑
        //, serverUrl: URL + "jsp/controller.jsp"
    , serverUrl: "/ueditor"      
  1. 設定url控制忽略

    沒有安全限制可以忽略

.antMatchers("/imgUpload").permitAll()
                .antMatchers("/videoUpload").permitAll()
                .antMatchers("/ueditor").permitAll()
                .antMatchers("/content").permitAll()      

到了這裡,後端資源就配置完畢

11. 打開index.html進行圖檔上傳設定

= UE.getEditor('editor');
    UE.Editor.prototype._bkGetActionUrl = UE.Editor.prototype.getActionUrl;
    UE.Editor.prototype.getActionUrl = function(action) {
        if (action == 'uploadimage' || action == 'uploadscrawl' || action == 'uploadimage') {
            return 'http://localhost:8211/imgUpload';
            //'http://localhost:8080/imgUpload';為方法imgUpload的通路位址
        else {
            return this._bkGetActionUrl.call(this, action);
        }
    }      

運作項目,發現上傳正常

Spring Boot內建Ueditor富文本編輯器,實作圖檔上傳,視訊上傳,傳回内容功能并且通過OSS轉換為連結并且解決Spring Security靜态資源通路以及跨域問題

12. 設定上傳圖檔傳回阿裡雲OSS連結

RequestMapping(value="/imgUpload")
    @ResponseBody
    public Map<String, Object> images (MultipartFile upfile, HttpServletRequest request, HttpServletResponse response){
        Map<String, Object> params = new HashMap<String, Object>();
        System.out.println("1111111111111");
        try{
            String url = ResourceUtils.getURL("").getPath()+upfile.getOriginalFilename();
            File folder = new File(url);
            upfile.transferTo(folder);
            url = OSSUtils.upload(folder, UUID.randomUUID().toString()+upfile.getOriginalFilename().substring(upfile.getOriginalFilename().lastIndexOf(".")));
            System.out.println(UUID.randomUUID().toString()+upfile.getOriginalFilename().substring(upfile.getOriginalFilename().lastIndexOf(".")));
            folder.delete();
            String fileName = upfile.getOriginalFilename();
            params.put("state", "SUCCESS");
            params.put("url", url);
            params.put("size", upfile.getSize());
            params.put("original", fileName);
            params.put("type", upfile.getContentType());

        } catch (Exception e){
            params.put("state", "ERROR");
        }
        return params;
    }      
  1. 設定富文本表單送出
<div>
    <h1>完整demo</h1>
<!--    <script id="editor" type="text/plain" style="width:1024px;height:500px;"></script>-->

    <form action="/content" method="post" >
        <textarea id="editor" name="content" type="text/plain" style="width:1024px;height:500px;">這裡寫你的初始化内容</textarea>
        <input type="hidden", id="content1" name="content1" >
        <button id="btn" onclick="getContent1()">送出</button>
    </form>
</div>      
  1. 表單送出設定傳回帶完全htnl标簽與标簽兩種
//這是我寫的,其他的不是
    function getContent1(){
        var arr = UE.getEditor('editor').getAllHtml();
        document.getElementById("content1").value = arr;
        //return UE.getEditor('editor').getContent();
    }      

順便學了一點JS知識

15. 設定上傳視訊并傳回阿裡雲OSS連結

  • 首先設定index.html
if (action == 'uploadimage' || action == 'uploadscrawl' || action == 'uploadimage') {
            return 'http://localhost:8211/imgUpload';
            //'http://localhost:8080/imgUpload';為方法imgUpload的通路位址
        }else if(action == "uploadvideo"){
            return 'http://localhost:8211/videoUpload';
        }
        else {
            return this._bkGetActionUrl.call(this, action);
        }      
  • 設定後端控制層
RequestMapping(value="/videoUpload")
    @ResponseBody
    public Map<String, Object> videos (MultipartFile upfile, HttpServletRequest request, HttpServletResponse response){
        Map<String, Object> params = new HashMap<String, Object>();
        System.out.println("1111111111111");
        try{
            String url = ResourceUtils.getURL("").getPath()+upfile.getOriginalFilename();
            File folder = new File(url);
            upfile.transferTo(folder);
            url = OSSUtils.upload(folder, UUID.randomUUID().toString()+upfile.getOriginalFilename().substring(upfile.getOriginalFilename().lastIndexOf(".")));
            System.out.println(UUID.randomUUID().toString()+upfile.getOriginalFilename().substring(upfile.getOriginalFilename().lastIndexOf(".")));
            folder.delete();
            String fileName = upfile.getOriginalFilename();
            params.put("state", "SUCCESS");
            params.put("url", url);
            params.put("size", upfile.getSize());
            params.put("original", fileName);
            params.put("type", upfile.getContentType());

        } catch (Exception e){
            params.put("state", "ERROR");
        }
        return params;
    }      
  1. 傳回富文本内容,并且設定成htnl檔案上傳到阿裡雲OSS最後傳回連結
@RequestMapping("/content")
    @ResponseBody
    public String findContent(String content, String content1) throws IOException {
        System.out.println("content1:"+content1);
        String url = ResourceUtils.getURL("").getPath()+UUID.randomUUID().toString()+".html";
        File folder = new File(url);
        FileWriter fileWriter = new FileWriter(folder);
        fileWriter.write(content1);
        fileWriter.flush();
        fileWriter.close();
        url = OSSUtils.upload(folder,UUID.randomUUID().toString()+".html");

        System.out.println("content:"+url);
        return url;
    }      

總結

  • 自己的總結

    現在基本的功能搜已經實作了,主要是還是內建在前端比較好,友善互動,後端直接寫接口就可以,現在他們應該是在決定用哪一個富文本編輯器以及最終要的把我需要的接口給我