前言

最近应上级要求,添加一个富文本编辑器,百度的Ueditor(主角来了);划重点2016年就停更了!
废话不多说,直接开始操作吧。
!!!建议看的时候仔细一点,因为很可能遗漏了某个地方就很抓狂!!!

相信你看完肯定会有收获的

1、先去GitHub官网上下载Ueditor(点这里)

下载完成之后解压出来,一会要复制文件的

注意:我这里直接开始导入操作,默认你会maven,vue,并且会使用IDEA工具

2、再下载一个jsp版本(我是用java写得)

此处也可以不下载,但是怕有童鞋整不明白,所以还是多下一个吧
第一个zip是整个源码,第二个是分离出来的,后面会涉及到修改源码

点我下载

3、复制文件

1、将ueditor1_4_3_3-utf8-jsp中的文件全部复制到 vue 项目的static目录或者public目录的 ueditor 文件夹下(自行创建),效果如图:

注:我的jsp文件夹已经删了,后面都移走了

2、将这个路径下ueditor-1.4.3.3\jsp\src\com\baidu\ueditor中的文件全部复制到 springboot 工程当中
如图:

3、引入maven

将下面这4个jar包引入工程中

注:因为我们上面引入了源码,所以第5个jar包就不需要引入

     <!--Ueditor--><dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId></dependency><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId></dependency><dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifactId></dependency><dependency><groupId>org.json</groupId><artifactId>json</artifactId><version>1.0.0</version></dependency>
这里上面 3 个可以直接通过 maven 引入,第 4 个可能会有问题(没问题的略过~)

笔者这里是通过 mvn 命令引入的,如下:

mvn install:install-file -Dfile=D:\DEV\work\erp_server_v4\src\web\WEB-INF\lib\proxool-0.9.1.jar -DgroupId=proxool -DartifactId=proxool -Dversion=0.9.1 -Dpackaging=jar

4、编写 Ueditor 组件

创建组件引入下面的 cssjs 文件

注:注意红色的框,引入的是 ueditor.all.js,别问为什么,血泪史~~
压缩之后会有莫名其妙的问题,还是别用的好

还需要注意文件引用的路径,根据自己的项目结构而定

功能和参数都是因地制宜的,难度不大。下面直接附上源码:

<template><div><script :id="editorId" type="text/plain"></script></div>
</template>
<script>
import '../../../public/ueditor/ueditor.config.js'
import '../../../public/ueditor/ueditor.all.js'
import '../../../public/ueditor/ueditor.parse.js'
import '../../../public/ueditor/lang/zh-cn/zh-cn.js'
import '../../../public/ueditor/themes/default/css/ueditor.css'
export default {name: 'UEditor',props: {/* 编辑器Id */editorId: {type: String,default: '',},/* 编辑器的内容 */value: {type: String,default: "",},/* 高度 */height: {type: Number,default: 300,}},data () {return {editor: null,config: {autoHeightEnabled: false,initialFrameHeight: this.height,initialFrameWidth: '100%',UEDITOR_HOME_URL: '/ueditor/',toolbars: [['source', //源代码'undo', //撤销'redo', //重做'bold', //加粗'italic', //斜体'underline', //下划线'strikethrough', //删除线'subscript', //下标'superscript', //上标'fontborder', //字符边框'blockquote', //引用'pasteplain', //纯文本粘贴模式'preview', //预览'horizontal', //分隔线'removeformat', //清除格式'time', //时间'date', //日期'cleardoc', //清空文档'insertcode', //代码语言'fontfamily', //字体'fontsize', //字号'paragraph', //段落格式'insertimage', //多图上传'edittd', //单元格属性'inserttable', //插入表格'deletetable', //删除表格'link', //超链接'emotion', //表情'spechars', //特殊字符'searchreplace', //查询替换'justifyleft', //居左对齐'justifyright', //居右对齐'justifycenter', //居中对齐'justifyjustify', //两端对齐'forecolor', //字体颜色'backcolor', //背景色'insertorderedlist', //有序列表'insertunorderedlist', //无序列表'fullscreen', //全屏'imagenone', //默认'imageleft', //左浮动'imageright', //右浮动'attachment', //附件'imagecenter', //居中'wordimage', //图片转存'lineheight', //行间距'autotypeset', //自动排版'touppercase', //字母大写'tolowercase', //字母小写]]}}},mounted () {/*** 初始化编辑器,并设置值*/this.editor = UE.getEditor(this.editorId, this.config);this.editor.addListener('ready',  () => {this.editor.setContent(this.value)})/*** 监听编辑器,当编辑器中输入内容时与父组件进行同步*/this.editor.addListener("contentChange",  () => {this.$emit('input',this.editor.getContent())})},methods: {getUEContent () {return this.editor.getContent()},setUEContent (value) {return this.editor.setContent(value)}},destroyed () {this.editor.destroy()}
}
</script>

这里提一嘴,创建每一个ueditor实例时一定要有不同的id,不然在同一个组件无法多次使用(害,该踩的坑让我来,一个都不少~)

5、写好另一个父组件引用我们刚刚完成的Ueditor组件

这里不具体实现,朋友们自己动手啦~
此时成功的显示出来即可,注意还不能上传图像

6、(重点)开始配置图像上传功能

1、将 ueditor1_4_3_3-utf8-jsp/jsp 文件夹下的 config.json 文件复制到 springboot 项目下的 resources 文件夹下
2、在后台编写 UEditorController 来代替 controller.jsp 文件

@RestController
public class UEditorController {@RequestMapping("/config")public String exec(HttpServletRequest request,HttpServletResponse response,@RequestParam(value = "action") String action) throws Exception {request.setCharacterEncoding("utf-8");response.setContentType("text/html");String rootPath = request.getSession().getServletContext().getRealPath("/");return new ActionEnter(request, rootPath).exec();}
}
解释

controller.jsp 这个文件主要是用来获取 config.json 中的内容,并返回过去,因为富文本编辑器在初始化时会调接口来访问这个文件中的内容
所以你在baidu的时候会发现有很多不一样的版本,没关系,目的都一样

这里我们获取的路径还会有问题,因此我们还有修改源码

修改一:修改 ConfigManager.java 文件中的 getConfigPath() 方法

 private String getConfigPath () {//      return this.parentPath + File.separator + ConfigManager.configFileName;// 修改源码try{return this.getClass().getClassLoader().getResource("config.json").toURI().getPath();} catch (URISyntaxException e) {e.printStackTrace();return null;}}

修改二:修改 BinaryUploader.java 文件中的 save() 方法(删除或注释掉)

public static final State save(HttpServletRequest request,Map<String, Object> conf) {if (!ServletFileUpload.isMultipartContent(request)) {return new BaseState(false, AppInfo.NOT_MULTIPART_CONTENT);}try {MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;MultipartFile multipartFile = multipartRequest.getFile(conf.get("fieldName").toString());if (multipartFile == null) {return new BaseState(false, AppInfo.NOTFOUND_UPLOAD_DATA);}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;long maxSize = ((Long) conf.get("maxSize")).longValue();if (!validType(suffix, (String[]) conf.get("allowFiles"))) {return new BaseState(false, AppInfo.NOT_ALLOW_FILE_TYPE);}savePath = PathFormat.parse(savePath, originFileName);String physicalPath = (String) conf.get("rootPath") + savePath;InputStream is = multipartFile.getInputStream();State storageState = StorageManager.saveFileByInputStream(is,physicalPath, maxSize);is.close();if (storageState.isSuccess()) {storageState.putInfo("url", PathFormat.format(savePath));storageState.putInfo("type", suffix);storageState.putInfo("original", originFileName + suffix);}return storageState;} catch (IOException e) {}return new BaseState(false, AppInfo.IO_ERROR);}

到这里启动工程访问http://localhost:8080/config?action=config应该能正常返回 config.json 中的内容了

如果访问不能正常返回的话,注意路径问题,
或者未知原因也有,其实里面bug挺多的,界面也过时了,但是耐不住人家功能强大…

修改三:修改 ueditor.all.js 文件

                var configUrl = me.getActionUrl('config'),// isJsonp = utils.isCrossDomainUrl(configUrl);isJsonp = false;

ctrl+f 找到并注释掉它,再补上 isJsonp = false;

注意:

使用了security的童鞋要放开链接访问权限相关的文件(资源)访问权限(如png,jpg等等)
这一点对后面的测试也很重要,能少走很多弯路!!!

7、修改配置文件

1、修改 config.json 文件


也就是说再上传成功后,会调用 http://localhost:8081/image/upload/ueditor/{time}/{filename} 来显示在文本框里面

没理解也不要紧,接着往下看,后面实践了就恍然大悟了

2、修改 ueditor.config.js 文件

再把controller放过来对照

@RestController
public class UEditorController {@RequestMapping("/config") //看这里!!!public String exec(HttpServletRequest request,HttpServletResponse response,@RequestParam(value = "action") String action) throws Exception {request.setCharacterEncoding("utf-8");response.setContentType("text/html");String rootPath = request.getSession().getServletContext().getRealPath("/");return new ActionEnter(request, rootPath).exec();}
}

这里就是编辑器初始化时,向服务器发送请求读取 config.json 文件的配置

3、编写上传文件的controller

放在这里方便你拷贝~

 @Autowiredprivate UEditorUpload uEditorUpload;@RequestMapping("/config")public String exec(HttpServletRequest request,HttpServletResponse response,@RequestParam(value = "action") String action,@RequestParam(value = "upfile", required = false) MultipartFile upfile) throws Exception {if (action.equals("config")) {request.setCharacterEncoding("utf-8");response.setContentType("text/html");String rootPath = request.getSession().getServletContext().getRealPath("/");return new ActionEnter(request, rootPath).exec();} else if (action.equals("uploadimage")) {UEditorFile uEditorFile = uEditorUpload.uploadImage(upfile);JSONObject jsonObject = new JSONObject(uEditorFile);return jsonObject.toString();}return "无效Action";}

4、补充注入方法和返回结果封装类(没错,不返回指定参数是用不了的!!)具体情况请看官网要求。
新建 UEditorUpload.java 源码如下:

(相信看到这里的朋友,有能力自己分析方法实现了上面,我偷懒去了)

    private Logger log = LoggerFactory.getLogger(UEditorUpload.class);private String path = ClassUtils.getDefaultClassLoader().getResource("").getPath();public UEditorFile uploadImage(MultipartFile file) throws IOException {log.info("UEditor开始上传文件");String fileName = file.getOriginalFilename();  //获取文件名//Ueditor的config.json规定的返回路径格式String returnPath = "/image/upload/ueditor/"+new Date().getTime()+"/"+fileName;File saveFile = new File(path+"static"+returnPath);if (!saveFile.exists()){saveFile.mkdirs();}file.transferTo(saveFile);  //将临时文件移动到保存路径log.info("UEditor上传文件成功,保存路径:"+saveFile.getAbsolutePath());UEditorFile uEditorFile = new UEditorFile();uEditorFile.setState("SUCCESS");uEditorFile.setUrl(returnPath);  //访问URLuEditorFile.setTitle(fileName);uEditorFile.setOriginal(fileName);return uEditorFile;}

String path = ClassUtils.getDefaultClassLoader().getResource("").getPath();
这是引用spring中的工具类来获取地址,有兴趣的话可以试试
getClass().getClassLoader().getResource(“文件”).toURI().getPath();


新建 UEditorFile.java 这个文件主要是按照上传文件返回格式而创建的,源码如下:

@Data
@NoArgsConstructor
@Accessors(chain = true)
public class UEditorFile {private static final long serialVersionUID=1L;private String state;private String url;private String title;private String original;@Overridepublic String toString() {return "{" +"state='" + state + '\'' +", url='" + url + '\'' +", title='" + title + '\'' +", original='" + original + '\'' +'}';}
}

整理到这里就可以去启动整个工程项目了

7、启动测试

ok的话就很nice,说明你成功了!

下面我总结一下我遇到的及其解决办法,由于已经写完了,错误截图就没有,后面找时间补上(求放过~)

1、读取不到 config.json 文件

1、检查读取路径是否正确,这个得自己一步步debug了
2、直接访问时记得带上参数action。。。(虽然时笨笨的问题,但是我发生了)
3、放开地址访问权限
4、检查文件是否被过滤

2、跨域问题可自行百度,方案挺多的

3、控制台显示http请求错误

1、认真检查配置文件路径
2、测试后端接口带上参数看看有没有问题
3、2中可以的话,看看vue组件是不是用的 ueditor.all.min.js,改成 ueditor.all.js,(我就是这里离谱的问题!!!,估计时压缩后的问题)

4、能选择图片,(多图上传按钮下)点击上传后,后端能拿到数据,也存下来图片,但是编辑器显示http错误 或者 服务器端错误

1、检查路径…(没错,还是检查路径)
2、返回的数据类型要是 string 类型的,或者说要 json 的字符串
3、返回的字符串没按照官网要求,具体可以翻上面,我将了

5、上传成功了,但是编辑器不能正常显示

我这里报的是跨域的错,但是其实不是的,这种情况还有很多,前面也出现了!!!
我把静态文件访问路径放开就能正常回显了,(我是需要认证的项目,不是demo~)

终于写完了,后续我在抽空写一个 demo 放到 gitee 上,可以参考自己理解后去写,更好一点

demo来了!!!点击这里

最后

感谢这位博主的分享@kshon,他的文章链接

springboot+vue整合百度的Ueditor(保姆级教程)相关推荐

  1. Vue脚手架的安装(保姆级教程)

    Vue脚手架的安装(保姆级教程) 文章目录 Vue脚手架的安装(保姆级教程) 1.下载vscode 2.node下载 5.Vue脚手架的安装 6.创建Vue项目 7.项目的运行 1.下载vscode ...

  2. 快速上手Springboot项目(登录注册保姆级教程)

    本文章对SpringBoot开发后端项目结构做了简单介绍,并示范了使用SpringBoot+MySQL实现登录的后端功能,与本博客的另一篇文章 Vue 实现登录注册功能(前后端分离完整案例) | Ma ...

  3. vue整合百度地图(关键字检索)

    百度地图 文章目录 百度地图 一.申请百度地图的密钥 二.官方示例 三.使用vue整合百度地图步骤说明 3.1 效果图: 3.2 方式一 vue脚手架2.0版本引用(不推荐): 3.3 方式二 封装成 ...

  4. springboot+Vue整合Luckysheet,实现在线编辑Excel表格

    springboot+Vue整合Luckysheet,实现在线编辑Excel表格 功能:页面嵌入Luckysheet表格组件,能够在线编辑Excel表格,实现表格的读取,保存功能(不支持导出为xls文 ...

  5. 保姆级教程——将springboot项目部署到阿里云服务器(小白包会)

    保姆级教程--将springboot项目部署到阿里云服务器(小白包会) 前言: 昨天本想着看论文,结果发现找的论文和课题不一致.那干点什么好呢?那就把我的毕业设计(一个springboot项目)部署到 ...

  6. 视频教程-springboot+Vue整合前后端分离权限后台管理系统-Java

    springboot+Vue整合前后端分离权限后台管理系统 拥有八年的Java项目开发经验,擅长Java.vue.SpringBoot.springCloud.spring.springmvc.myb ...

  7. SpringBoot+Vue整合支付宝沙箱支付

    SpringBoot+Vue2整合实现支付宝沙箱支付 原创不易,转载请注明!!原创不易,转载请注明!!原创不易,转载请注明!!原创不易,转载请注明!!原创不易,转载请注明!! 在进行电脑网站开发时我们 ...

  8. vue+element项目 手机号、邮箱校验 保姆级教程

    vue+element项目 手机号.邮箱校验 保姆级教程 (包含注意点) 先看案例:在vue+element项目中给表单中的手机号和邮箱做校验 标题先说注意点 prop黄色框框起来的一定要有 废话不多 ...

  9. Flutter开发百度地图之定位,保姆级教程(2)

    未经本人同意,禁止转载! 前几天开发flutter百度地图,总算是把第一步走通了,这几天把定位功能开发了一下.记录一下,所谓取之于CSDN用之于CSDN. 下面描述的工程是配置Android的,ios ...

  10. SpringBoot 配置 generator代码生成+knife4j接口文档(2种模板设置、逻辑删除、字段填充 含代码粘贴可用)保姆级教程(注意事项+建表SQL+代码生成类封装+测试类)

    保姆级教程,逻辑删除及字段自动填充设置,特别要说明的是本次用的是MySQL数据库,如果使用Oracle数据库是,数据库配置需要改变,数据库表一定要大写,否则无法生成代码. 数据库表 CREATE TA ...

最新文章

  1. Python正则表达式常用的15个符号整理
  2. (转)全文检索技术学习(一)——Lucene的介绍
  3. 对A1A2A10B1B2N12排序
  4. httpd 服务的两个节点的HA
  5. Win XP环境Tuxedo8.1安装、配置指南
  6. 如何从低端面畜到高端面霸
  7. Linux系统下如何配置SSH?如何开启SSH?
  8. php 查询cpu使用率,php获取CPU使用情况的代码
  9. Linux实验室 CentOS关机大法
  10. 一文搞懂什么是禁忌搜索算法Tabu Search【附应用举例】
  11. 24岁,一门手艺,年入百万
  12. 为什么一个操作系统连个进程启动日志都没有
  13. 2022年最新用最简单粗暴的方式讲解:pytest简介,框架基础应用,运行方式,失败用例重跑。直击核心
  14. Excel中的Array Formula
  15. 关于165的(ORCAP-1192)
  16. 什么是API Mock测试?
  17. hgroup元素与figcaption元素的结合使用
  18. Python Pandas库 Series.dt.tz_localize()和 Series.dt.tz_convert()的简单使用
  19. 将系统从机械硬盘迁移至固态硬盘上
  20. 在WINDOWS运行框中能够输入的命令有多少?(转)

热门文章

  1. HTTP协议发展历史
  2. python批量读取nc文件_Python读取nc文件的入门级操作
  3. 世界质量大师登场,告诉你质量的最大秘密!【优思学院】
  4. 数据库课程设计 论坛系统—— 系统详细设计说明书
  5. ISO18000-6B和ISO18000-6C(EPC C1G2)标准的优点区别
  6. win10下安装adb
  7. 单片微型计算机原理和应用答案,《单片微机原理及应用》 试卷A及参考答案
  8. 《深入浅出WPF》读书笔记
  9. python自动更新国内IP地址合集
  10. 小米8对一加6打开软件速度测试,小米 8 对决一加 6,谁更值得买?