SpringBoot 整合 UEditor 详细教程(一)

2023-10-30

SpringBoot 整合 UEditor 详细教程(一)| 整合教程


官方文档:http://fex.baidu.com/ueditor/.
项目地址:https://github.com/fex-team/ueditor.
官方源码zip包(UTF-8格式):ueditor-1.4.3.3.zip(github下载过慢)

一、下载源码包
1.由于官网下载过慢,我在上面贴了百度云的下载链接(JSP、UTF-8版)

下载后方式项目的放入静态文件夹static下:
在这里插入图片描述


2.引入 pom 依赖
<!--    UEditor    -->
<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.2</version>
</dependency>
<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.9</version>
</dependency>

3.改写以前jsp获取 config.json(上传相关配置) 文件的方法
注意:
  • 图片不上传到云服务器的话需要做映射,可参考下一篇的踩坑文章

  • 这里我写的上传方法在本地可以使用,然后由于部署到线上时出现config.json不能读取,就将config.json文件单独放出来了,具体可看代码;

  • 还有一个问题就是上传图片,本地映射的方式在Linux服务器无法正常显示,搞了差不多一天,后面还是改成通过OSS上传到阿里云。(这里OSS上传代码就不贴了)

  • 如果大家服务器改好了可告诉博主,博主进行实践和更新。

这里改写了原来百度编辑器的两个类:ActionEnterConfigManager
大致就是将里面的内容重写一遍(ActionEnterRewrite、ConfigManagerRewrite ),用于部署到linux环境时打印日志定位问题,大家可重写也可重写,主要用于定位每次获取config.json的获取路径

重写文件下载地址:

/**
 * 描述: 百度编辑器引入
 * 创建人: 慌途L
 */
@Slf4j
@RestController
public class UEditorController {
    /**
     * 获取config,json配置文件
     */
    @RequestMapping("/ueditor/config")
    public void getConfigInfo(HttpServletRequest request, HttpServletResponse response) {
        response.setContentType("application/json");

        String rootPath = "";
        // 判断当前系统是否是Windows系统
        if(isWindowsSystem()){
            rootPath = ClassUtils.getDefaultClassLoader().getResource("").getPath() + "static/ueditor/jsp";
        } else {
            // 将config.json文件放在jar包同级目录下
            rootPath = "/usr/local/yunapp-backend/service";
        }
        log.info("rootPath:{}", rootPath);
        try {
            response.setCharacterEncoding("UTF-8");
            String exec = new ActionEnterRewrite(request, rootPath, "/config.json").exec();
            log.info("exec:{}", UnicodeUtil.toString(exec));
            PrintWriter writer = response.getWriter();
            writer.write(exec);
            writer.flush();
            writer.close();
        } catch (IOException | JSONException e) {
            e.printStackTrace();
        }
    }

    /**
     * UEditor 上传图片(单个或多个)---Windows使用(主要将config.json中的imageUrlPrefix改为本地地址)
     * @return  返回提示信息
     */
    @RequestMapping(value = "/ueditorUpload", method = RequestMethod.POST)
    public Object upLoadImgToWindows(MultipartFile upfile){
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("state", "上传失败");

        if (Objects.isNull(upfile)) {
            return map;
        }

        String oldName = upfile.getOriginalFilename();
        String timeFileName = DateHelper.getDateStr(new Date());

        // 判断当前系统是否是Windows系统
        boolean system = isWindowsSystem();
        String fileName = system ? FileUtils.upLoadFile(upfile,"F:/upload/admin/article/" + timeFileName)
                : FileUtils.upLoadFile(upfile,imgUrl + "/" + timeFileName);
        if (StringUtils.isNotBlank(fileName)) {
            map.put("state", "SUCCESS");
            // 图片url 浏览器不能直接访问项目外目录的图片等文件,需要做虚拟路径映射
            // 这个路径的是在配置类里指定的映射到本地的绝对路径
            if(system){
                map.put("url", "/upload/admin/article/" + timeFileName + "/" + fileName);
            } else {
                map.put("url", "/" + mappingUrl + "/" + timeFileName + "/" + fileName);
            }
            //图片名称,这个会显示在输入框里
            map.put("title", fileName);
            //图片原名称
            map.put("original", oldName);
            //文件类型 .+后缀名
            map.put("type", fileName.substring(fileName.lastIndexOf(".")));
            //文件大小(字节数)
            map.put("size", upfile.getSize());
        }
        log.info("map:{}", map);
        return map;
    }

    /**
     * 判断当前系统是否是Windows系统
     * @return true:Windows系统,false:Linux系统
     */
    private boolean isWindowsSystem(){
        String property = System.getProperty("os.name").toLowerCase();
        return property.contains("windows");
    }

}

FileUtils.java

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.Random;

/**
 * 功能 : 上传文件工具类
 * 创建人 : 慌途L
 */
@Slf4j
public class FileUtils {

    public static String upLoadFile(MultipartFile file, String path) {

        if(file.isEmpty()){
            log.info("文件为空!");
            return null;
        }
        String fileName = file.getOriginalFilename();
        int size = (int) file.getSize();
        log.info(fileName + "-->" + size);

        // 取得文件的后缀名。
        String ext = fileName.substring(fileName.lastIndexOf(".") + 1).toUpperCase();

        String newFileName =
                System.currentTimeMillis() / 1000 + new Random().nextInt(100000)+"." + ext;

        //String path = "F:/test" ;
        File dest = new File(path + "/" + newFileName);
        if(!dest.getParentFile().exists()){ //判断文件父目录是否存在
            dest.getParentFile().mkdir();
        }
        try {
            file.transferTo(dest); //保存文件
            return newFileName;
        } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        }
    }
}


4.修改 ueditor.config.js 文件中的入口路径

这里是百度编辑器初始化时读取config.json的方法路径

var server_url = window.location.protocol+"//"+window.location.hostname+":"+window.location.port;

在这里插入图片描述


5.测试文件 Demo.html:

(我这里用的是thymeleaf模板,有一些坑,就是在 script 标签中使用 UE.getEditor 时,需要使用下面的标签)

<script type="text/javascript" th:inline="none">
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:se="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- 配置文件 -->
    <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="/ueditor/lang/zh-cn/zh-cn.js"></script>
</head>

<body>
    <div>
        <script id="ueditorContent" name="content" style="min-height: 500px"></script>
    </div>
</body>

<!-- 实例化编辑器 -->
<script type="text/javascript" th:inline="none">
    UE.Editor.prototype._bkGetActionUrl = UE.Editor.prototype.getActionUrl;
    console.log(UE.Editor.prototype.getActionUrl)
    console.log(UE.Editor.prototype._bkGetActionUrl)
    UE.Editor.prototype.getActionUrl = function(action) {
        if (action === 'uploadimage') {
            return '/ueditorUpload';// 此路径跟ueditor.config.js中的服务器统一请求接口路径一样,在同一个controller中
            // return 'http://localhost:8090/upLoadImg';//自定义别的请求接口的需要加上IP和端口
        } else {
            return this._bkGetActionUrl.call(this, action);
        }
    }

    var uee = UE.getEditor('ueditorContent', {
        toolbars: [[
            'fullscreen', 'source', '|', 'undo', 'redo', '|',
            'bold', 'italic', 'underline', 'fontborder', 'strikethrough', 'superscript', 'subscript', 'removeformat', 'formatmatch', 'autotypeset', 'blockquote', 'pasteplain', '|', 'forecolor', 'backcolor', 'insertorderedlist', 'insertunorderedlist', 'selectall', 'cleardoc', '|',
            'rowspacingtop', 'rowspacingbottom', 'lineheight', '|',
            'customstyle', 'paragraph', 'fontfamily', 'fontsize', '|',
            'directionalityltr', 'directionalityrtl', 'indent', '|',
            'justifyleft', 'justifycenter', 'justifyright', 'justifyjustify', '|', 'touppercase', 'tolowercase', '|',
            'link', 'unlink', 'anchor', '|', 'imagenone', 'imageleft', 'imageright', 'imagecenter', '|',
            'simpleupload', 'insertimage', 'map', 'pagebreak', 'template', 'background', '|',
            'horizontal', 'date', 'time', 'spechars', '|',
            'inserttable', 'deletetable', 'insertparagraphbeforetable', 'insertrow', 'deleterow', 'insertcol', 'deletecol', 'mergecells', 'mergeright', 'mergedown', 'splittocells', 'splittorows', 'splittocols', 'charts', '|',
            'preview', 'searchreplace', 'drafts'
        ]]
    });
</script>

</html>

6.回显的时候需要使用以下代码:
UE.getEditor('ueditorContent').execCommand('insertHtml', content);
  • ueditorContent:百度编辑器的ID
  • content:回显的内容

7.测试上传图片(这里的单图和多图上传都是调用同一个接口,只是多图为多次调用)

在这里插入图片描述
在这里插入图片描述


下一篇为遇到的踩坑点:SpringBoot 整合 UEditor 详细教程(二)| 遇到的问题.

具体踩坑点:

  • 1.自定义 toolbars 时出现 Could not parse as expression 异常
  • 2.前端报错:请求后台配置项http错误,上传功能将不能正常使用
  • 3.报错:“\u914d\u7f6e\u6587\u4ef6\u521d\u59cb\u5316\u5931\u8d25”(配置文件初始化失败)
  • 4.配置上传图片,报错 : 无效的Action
  • 5.注释多图上传里面的其他按钮
  • 6.注释部分功能无法使用的代码
  • 7.保存成功后无法正常显示文字和图片,或显示为空白
  • 8.部署到服务器又出现了第3点的问题,加载不到config.json文件

参考网址:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SpringBoot 整合 UEditor 详细教程(一) 的相关文章

随机推荐

  • m1 mac 使用 obs + BlackHole 内录电脑音频

    直接 obs 是内录不了的 由于 macOS 的限制 无法获取桌面音频 于是使用 BlackHole Github 工具 该方案的原理是将电脑音频同时输出到你的设备 耳机 扬声器等 BlackHole 然后让 OBS 获取 BlackHol
  • Lambda表达式【C++语法】

    C L a m b d a
  • 测试驱动开发(TDD)实践与技巧

    文章目录 引言 Google Mock 测试用例结构 断言 经典式断言 Hamcrest 断言 测试驱动开发 第一个示例 开场白 开始吧 去掉不干净的代码 增量性 fixture 设置 思索与测试驱动开发 测试驱动与测试 测试驱动开发基础与
  • Android app多渠道打包的流程与源代码示例

    Android app多渠道打包的流程与源代码示例 多渠道打包是指通过一次构建过程生成适用于不同应用商店 市场或渠道的多个APK文件 这样可以方便开发者将应用同时发布到多个平台上 提高应用的覆盖率和下载量 本文将介绍实现多渠道打包的步骤 并
  • 静态路由实验(思科Cisco)

    思科静态配置命令 静态路由的配置命令如下 router config ip route 目的网络 网络掩码 下一跳地址 出接口 默认路由的配置命令如下 router config ip route 0 0 0 0 0 0 0 0 下一跳地址
  • kali linux之手动漏洞挖掘三(sql注入)

    服务器端程序将用户输入作为参数作为查询条件 直接拼写sql语句 并将结果返回给客户端浏览器 如判断登录 select from users where user uname and password pass select from use
  • 看完这篇 教你玩转渗透测试靶机vulnhub——DC7

    Vulnhub靶机DC7渗透测试详解 Vulnhub靶机介绍 Vulnhub靶机下载 Vulnhub靶机安装 Vulnhub靶机漏洞详解 信息收集 SSH登入 漏洞发现与利用 提权 获取flag Vulnhub靶机渗透总结 Vulnhub靶
  • 使用C#编写程序屏蔽键盘输入

    使用C 编写程序屏蔽键盘输入 在C 中 我们可以使用System Windows Forms命名空间下的Keyboard类来实现屏蔽键盘输入的功能 下面是一段示例代码 演示了如何屏蔽键盘输入 using System using Syste
  • Java自学视频整理

    1 Java基础视频 张孝祥JAVA视频教程 完整版 RMVB 东西网 历经5年锤炼 史上最适合初学者入门的Java基础视频 传智播客 张孝祥2010年贺岁视频 Java高新技术 传智播客 Java多线程与并发库高级应用 传智播客 尚学堂J
  • 区块链自定义节点

    本地自定义节点 1 cmd中 安装好geth后 cmd geth help 检查是否geth是否安装好 然后输入命令geth datadir testNet dev rpc console 自定义本地的节点 2 metaMask 再在met
  • SOCKET套接字

    操作系统提供 用于开发网络应用的一系列API函数接口 可以称为套接字函数 所有的系统平台都有对SOCKET套接字的兼容和实现 虽然网络环境中有大量的协议类型 但是绝大多数协议都是采用TCP和UDP 也就是说很多软件或网站的访问与链接一样使用
  • Java+SSM+Vue 毕业设计 汽车租赁系统(含源码+论文)

    文章目录 1 项目简介 2 实现效果 2 1 界面展示 3 设计方案 3 1 概述 3 2 系统流程 3 3 系统结构设计 4 项目获取 1 项目简介 Hi 各位同学好呀 这里是M学姐 今天向大家分享一个今年 2022 最新完成的毕业设计项
  • Linux内核的Oops

    简介 什么是Oops 从语言学的角度说 Oops应该是一个拟声词 当出了点小事故 或者做了比较尴尬的事之后 你可以说 Oops 翻译成中国话就叫做 哎呦 哎呦 对不起 对不起 我真不是故意打碎您的杯子的 看 Oops就是这个意思 在Linu
  • kubernetes介绍和安装(1.25版本)

    kubernetes介绍和安装 1 25版本 K8S 是什么 K8S官网文档 https kubernetes io zh docs home K8S 是Kubernetes的全称 源于希腊语 意为 舵手 或 飞行员 基于go语言开发 官方
  • 二、读取编码器数值实现电机测速—2 、配置编码器;

    读取编码器数值实现电机测速 电机系列 二 读取编码器数值实现电机测速 2 配置编码器 encoder h encoder c main c 3 测速 电机系列 二 读取编码器数值实现电机测速 2 配置编码器 encoder h ifndef
  • Apollo SpringBoot 客户端使用

    1 简介 Apollo 阿波罗 是携程框架部门研发的分布式配置中心 能够集中化管理应用不同环境 不同集群的配置 配置修改后能够实时推送到应用端 并且具备规范的权限 流程治理等特性 适用于微服务配置管理场景 服务端基于Spring Boot和
  • 时间序列分析中统计模型statsmodels.tsa.arima_model

    10条消息 时间序列分析中的 statsmodels tsa arima model被抛弃了 如何解决 berry的博客 CSDN博客 根据某个期货的收盘价用ARMA GARCH拟合三年日收益率 然后求出月条件波动率平均值 得到一个月波动率
  • zk集群的选举和数据的同步

    zab协议 zookeeper为了保证数据的 致性 使 了ZAB Zookeeper Atomic Broadcast 协议 这个协议解决了Zookeeper的崩溃恢复和主从数据同步的问题 集群的选举 集群刚启动的时候 在集群启动的时候 每
  • new!!!修复geonode4.1.0保存地图Network error

    操作都是在geonode拉取后的源码中修改 Given that you must understand why you are getting a timeout which is most probably caused by some
  • SpringBoot 整合 UEditor 详细教程(一)

    SpringBoot 整合 UEditor 详细教程 一 整合教程 官方文档 http fex baidu com ueditor 项目地址 https github com fex team ueditor 官方源码zip包 UTF 8格