Ueditor 百度强大富文本Springboot 项目集成使用(包含上传文件和上传图片的功能使用)简单易懂,举一反三

news2024/9/24 23:16:59

Ueditor 百度强大富文本Springboot 项目集成使用

  • 首先如果大家的富文本中不考虑图片或者附件的情况下,只考虑纯文本且排版的情况下我们可以直接让前端的vue来继承UEditor就可以啦。但是要让前端将那几个上传图片和附件的哪些功能给阉割掉!

  • 然后就是说如果考虑到了上传图片或者视频和附件那么咱们还是用的前后分离的项目,那么我们就需要后台去做一些调整来职称前端上传了功能啦。(市面上有很多富文本编辑器,而且现在的UEditor的前端UI是很丑的,因为现在都2023年啦。但是耐不住人家功能丰富而且免费),那么我刚开始了解的这个也是无从下手,在众多博客和文档中找到了一条出路然后随便做下笔记,让大家不在急躁乏味奥利给!

  • 我在网上看了一大推的资料发现有很多不一样的案例实现,但是说的不是复杂就是特别的简单且抽象无从下手,废话不多说怎怎么直接开始

    首先我们去官网,咱们将zip包下载下来之后解压,注意要下载JSP使用说明的那个链接的zip包,因为他是github可能打不开链接地址,那么就可以去maven 去下载,但是maven下载的只有咱们后台用到的,前端的就要还是去官网下载,然后maven也写在这里啦

<!-- https://mvnrepository.com/artifact/com.gitee.qdbp.thirdparty/ueditor -->
<dependency>
    <groupId>com.gitee.qdbp.thirdparty</groupId>
    <artifactId>ueditor</artifactId>
    <version>1.4.3.6</version>
</dependency>

官网下载地址
在这里插入图片描述

然后在jsp中里面会存在一个 lib文件夹,然后是里面是有一个是config.json 这个是比较重要的一个配置文件一会我们回去修改其中的内容信息,纳闷我们现在将需要的jar包考出来是,就在lib 下面 


将文件引入到项目之中的resouces/lib 下 然后添加xml文件的依赖

<dependency>
    <groupId>com.gitee.qdbp.thirdparty</groupId>
    <artifactId>ueditor</artifactId>
    <version>1.4.3.6</version>
    <classifier>lib</classifier>
    <scope>system</scope>
    <systemPath>${project.basedir}/src/main/resources/lib/ueditor-1.4.3.6.jar</systemPath>
</dependency>

在这里插入图片描述

  • 好的现在已经完成了很大一部分啦,后面就是需要写代码啦。啦啦啦
    首先大家要是试过Ueditor的官网demo之后会发现会调用一个config 的接口,但是现在是没有这个接口的,而且这个接口是一个 根据不同的请求参数来表示不同的请求 比如: config?action=config 初始化,config?action=uploadimage 上传图片,config?action=uploadfile 上传文件 这个则初始化后台的一个接口就相当于进屋要先拿钥匙开门,然后才能操作 上传功能要不然前段的上传图片连弹框都弹不出来。那么这个钥匙就是要从我们后面获取,每次进入都要调用config?action=config 初始化。

在这里插入图片描述

Controller
控制层中只需要注意action 的参数名称 里面有三个 config,uploadimage,uploadfile 其实上传文件和图片只是存储路径不一样,这个参数并不是咱们定义的而是在上面所说的config.json,我将其中的无用配置删掉啦就留下了 上传图片和文件的
这里原文件中有注释大家可以看一下,所以咱们得那个接口参数就是这些,要是咱们接口名称或者传参的参数名称不叫这个,咱们就需要让两者保持一致。

/**
 * Ueditor富文本控制层
 * @author ZMH
 * @date 24/7/2023 2:33 下午
 */
@Slf4j
@RestController
@RequestMapping("/ueditor")
public class UEditorController {

    @Autowired
    private UEditorUpload uEditorUpload;

    @PassToKen
    @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")) {
            UEditorFileVo uEditorFile = uEditorUpload.uploadImage(upfile);
            JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(uEditorFile));
            return jsonObject.toJSONString();
        } else if (action.equals("uploadfile")) {
            UEditorFileVo uEditorFile = uEditorUpload.uploadFile(upfile);
            JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(uEditorFile));
            return jsonObject.toJSONString();
        }
        return "无效Action";
    }
}

service
这里我就写了两个上传其实其他的和这个一样只不过多一样,就是上传到服务器上然后返回相应的东西足以让前端展示就可以啦。

/**
 * Ueditor上传
 * @author ZMH
 */
@Service
@Slf4j
public class UEditorUpload {

    @Value("${path.ueditor}")
    private String ueditorFilePath;//ueditor文件存储路径

    /**
     * 上传image
     * @author ZMH
     * @param file
     * @return UEditorFile
     */
    public UEditorFileVo uploadImage(MultipartFile file) throws IOException, BaseException {
        log.info("UEditor开始上传文件");
        if (ObjectUtils.isEmpty(file)){
            log.warn("upfile 文件不能为空!");
            throw new BaseException("upfile 文件不能为空!");
        }
        String fileName = file.getOriginalFilename();  //获取文件名
        //Ueditor的config.json规定的返回路径格式 上传成功之后会返回returnPath
        String returnPath = "/upload/image/"+new Date().getTime()+"/"+fileName;
        File saveFile = new File(ueditorFilePath+returnPath);
        if (!saveFile.exists()){
            saveFile.mkdirs();
        }
        file.transferTo(saveFile);
        log.info("UEditor上传文件成功,保存路径:"+saveFile.getAbsolutePath());
        UEditorFileVo uEditorFile = new UEditorFileVo();
        uEditorFile.setState("SUCCESS");
        uEditorFile.setUrl(returnPath);  //访问URL
        uEditorFile.setTitle(fileName);
        uEditorFile.setOriginal(fileName);
        return uEditorFile;
    }

    /**
     * 上传文件
     * @author ZMH
     * @param file
     * @return UEditorFile
     */
    public UEditorFileVo uploadFile(MultipartFile file) throws IOException, BaseException {
        log.info("UEditor开始上传文件");
        if (ObjectUtils.isEmpty(file)){
            log.warn("upfile 文件不能为空!");
            throw  new BaseException("upfile 文件不能为空!");
        }
        String fileName = file.getOriginalFilename();  //获取文件名
        //Ueditor的config.json规定的返回路径格式
        String returnPath = "/upload/file/"+new Date().getTime()+"/"+fileName;
        File saveFile = new File(ueditorFilePath+returnPath);
        if (!saveFile.exists()){
            saveFile.mkdirs();
        }
        file.transferTo(saveFile);
        log.info("UEditor上传文件成功,保存路径:"+saveFile.getAbsolutePath());
        UEditorFileVo uEditorFile = new UEditorFileVo();
        uEditorFile.setState("SUCCESS");
        uEditorFile.setUrl(returnPath);  //访问URL
        uEditorFile.setTitle(fileName);
        uEditorFile.setOriginal(fileName);
        return uEditorFile;
    }

}

实体类 uEditorFile


/**
 * UEditorFileVo
 * @author ZMH
 */
@Data
@NoArgsConstructor
@Accessors(chain = true)
public class UEditorFileVo {

    private static final long serialVersionUID=1L;

    private String state;

    private String url;

    private String title;

    private String original;

    @Override
    public String toString() {
        return "{" +
                "state='" + state + '\'' +
                ", url='" + url + '\'' +
                ", title='" + title + '\'' +
                ", original='" + original + '\'' +
                '}';
    }
}

到这里已经将代码层面改好啦,然后呢就是最恶心的环节啦,那就是他们的源码里参了一点点西东,那就是BUG,那就是在这个jar包中的 getConfigPath() 方法,这里的获取config路径是不对的,我们需要改一下这个代码,可以使用修改源码或者重写来修改这里的源码,重写就是依靠java 的类加载器如果本地有就去加载本地的类,如果本地没有就去加载其他的,这里我是修改源码实现的。这里就不用大家改了怕累着大少爷,那既然是为大少爷做事,就要优雅。
这里是我改完的源码百度网盘链接: https://pan.baidu.com/s/1tU0uD1IwrMH2Xidcf5h0Dw?pwd=38vc 提取码: 38vc 如果大家好奇我改的什么idea会有对比功能,可以查看一下。其实就是换了获取config.json的路径变为了动态,下载了之后换掉lib下的包。

//在启动类中加入
//对应的配置文件也要有path.ueditorConfigPath 参数信息
@Value("${path.ueditorConfigPath}")
private String ueditorConfigPath;

//main中加入
System.setProperty("ueditor_config_path",ueditorConfigPath);
  • 到这里就可以上传啦,但是回显没有成功,回显其实就是上传成功之后的 url 和咱们初始化的 config 里面的 前缀也就是
    fileUrlPrefix的值和imageUrlPrefix的值,拼起来就可以啦。这里我采用的nginx,到这里也就结束啦。
    然后说一下不推荐的方式,不推荐纯后台集成,不推荐将config.json和保存的路径放在resouces下,这样会导致在本地可以访问到config.json,打完包之后是访问不到的,路径是jar包之内的路径,如果大家初始化有问题,那就记得去打印下你们的config.json
    路径,然后去顺着找一下看看存不存,还有就是一个那个上传到 resouces下的附件虽然说不用去开nginx 直接可以通过
    项目的地址加文件地址可以预览但是呢,就会导致后续发的jar包将之前的内容覆盖掉,导致内容丢失。还是建议大家分开,然后就是这个config.json
    到时候前端是直接将这个模块扔到VUE项目中的,我可以引用前端的config.json。改为前端的config.json地址既可,那样保持一套还好维护
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/798024.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

安装python需要多大内存,python下载安装包多大

大家好&#xff0c;小编来为大家解答以下问题&#xff0c;安装python需要多大内存&#xff0c;python安装占多大空间&#xff0c;现在让我们一起来看看吧&#xff01; 1、pytorch包有多大 938.79MB。pytorch包有938.79MB&#xff0c;pytorch离线安装包是一个不错的学习资源&am…

【CMake保姆级教程】CMake图文安装教程

文章目录 一、CMake概况二、安装Ubuntu CMake三、简单的CMake实验如何使用CMake测试代码执行CMake 总结 一、CMake概况 CMake 是一个项目构建工具&#xff0c;并且是跨平台的。关于项目构建我们所熟知的还有Makefile&#xff08;通过 make 命令进行项目的构建&#xff09;&…

【Docker consul的容器服务更新与发现】

文章目录 一、Consul 的简介&#xff08;1&#xff09;什么是服务注册与发现&#xff08;2&#xff09;什么是consul 二、consul 部署1、consul服务器1. 建立 Consul 服务2. 查看集群信息3. 通过 http api 获取集群信息 2、registrator服务器1. 安装 Gliderlabs/Registrator2. …

AcWing 算法基础课二 数据结构 链表 栈 队列 并查集 哈希表

单链表. AcWing. 826.单链表 import java.util.Scanner; public class Main{static int[] e new int[100010];//结点i的值static int[] ne new int[100010];//结点i的next指针static int idx,head;//head是头结点&#xff0c;idx存当前已经用到了哪个点public static void i…

Cpp02 — 内联函数、auto关键字、范围for、nullptr

前言&#xff1a;本文章主要用于个人复习&#xff0c;追求简洁&#xff0c;感谢大家的参考、交流和搬运&#xff0c;后续可能会继续修改和完善。 因为是个人复习&#xff0c;会有部分压缩和省略。 一、内联函数 C语言为了减少小函数的栈帧开销&#xff0c;提供了宏函数&#x…

SpingBoot整合Swagger和Hibernate-Validate练习

需求&#xff1a;用SpingBootSwaggerHibernate-Validate集成一个demo&#xff0c;用Swagger查看Controller的接口文档。Swagger接口包括Controller的请求和返回&#xff0c;用Hibernate-Validate校验Controller的请求参数的合法性。目前只需要校验非空即可。 1.新建一个Springb…

python 将pdf文件转图片

有小伙伴问了怎么将 pdf文件转图片的问题&#xff0c;我百度了一波儿&#xff0c;搞了以下python代码给他封装成exe工具了。 中途打包踩了个坑&#xff0c;python进程池的问题&#xff0c;本地运行没啥问题&#xff0c;打包好的exe文件双击就会使电脑内存爆破卡死&#xff0c;…

IT行业有哪些工资高、又有前景的岗位?

“IT行业涵盖了广泛的职位和领域&#xff0c;其中一些职位包括软件工程师、系统管理员、数据库管理员、网络工程师、UI/UX设计师、移动应用开发者、项目经理、IT顾问和技术支持工程师等” ——高薪岗位 那么&#xff0c;岗位如此之多&#xff0c;如何选择学习方向呢&#xff1…

蓝牙耳机啥牌子好?经销商盘点线下热销蓝牙耳机排行榜

经营蓝牙耳机已经三年了&#xff0c;随着蓝牙耳机的普及&#xff0c;蓝牙耳机已成为人手必备&#xff0c;很多朋友在挑选时会咨询我的意见&#xff0c;不知道蓝牙耳机啥牌子好&#xff0c;为此我整理了店铺内热销蓝牙耳机排行榜&#xff0c;想知道实体店铺哪些蓝牙耳机品牌最受…

面向对象编程:深入理解内部类与抽象类的使用

文章目录 一、内部类使用&#xff1a;1.1 成员内部类&#xff1a;1.1.1 成员内部类的主要特点是&#xff1a; 1.2 局部内部类&#xff1a;1.2.1 局部内部类的主要特点是&#xff1a;1.2.2 局部内部类通常用于以下情况&#xff1a; 1.3 静态内部类&#xff1a;1.3.1 静态内部类的…

微服务01,初始,拥抱他,最后爱上他,mmm

俗话说乱花渐欲迷人眼&#xff0c;学习微服务应该从哪开始学呢 从这张表去学微服务 微服务全家桶&#xff1a;走进 Spring Cloud 的世界 了解 Spring Cloud 框架的功能定位&#xff0c;以及它和 Spring Boot 之 间的关系。除此之外&#xff0c;我还会详细讲解 Spring Cloud 的…

KMP算法的及其原理

KMP算法 首先 我们先了解一下 KMP算法的作用 str1 和str2 字符串 如果str1中包含str2 那么返回头位置 如果不包含返回-1 首先 我们先加入一个概念: 有一个next数组 next[i]的值为 str2 中 以i-1位置为结尾的字符串中 最长相同前缀后缀为多长(相同前缀后缀 不是对称 aba 中相…

数字化转型与百数低代码平台:创新商业模式的商机突破口

随着科技的不断进步和全球经济的快速发展&#xff0c;企业数字化转型已经成为当今商业领域的热门话题。 根据Gartner的《2023年度董事会调查》显示&#xff0c;数字化转型已然是当今企业商业战略的一大基石&#xff0c;中国有36%的企业将数字化转型作为企业最优先的业务。 这表…

windows环境下,安装elasticsearch

jdk ElasticSearch是基于lucence开发的&#xff0c;也就是运行需要java jdk支持。 我下载了 elasticsearch-8.9.0-windows-x86_64.zip&#xff0c;带了OpenJDK。 ElasticSearch下载 https://www.elastic.co/downloads/elasticsearch 安装ElasticSearch 下载安装包后解压 修…

WMS仓储管理系统的建设理念包括哪些内容

WMS仓储管理系统是物流供应链管理领域中的重要组成部分&#xff0c;主要用于仓储过程的计划、控制和管理。WMS仓储管理系统解决方案可以有效协调人、设备和仓库资源&#xff0c;提高仓储效率、降低成本、确保准确性&#xff0c;为企业的物流运输及整个生产活动提供有力保障。那…

综合案例(面向对象)

使用面向对象思想完成数据读取和处理基于面向对象思想重新认知第三方库使用&#xff08;PyEcharts&#xff09; 数据分析案例 某公司&#xff0c;有2份数据文件&#xff0c;现需要对其进行分析处理&#xff0c;计算每日的销售额并以柱状图表的形式进行展示。 数据内容 综合案…

【Terraform学习】Terraform-docker部署快速入门(快速入门)

Terraform-docker部署快速入门 实验步骤 创建 EC2 IAM 角色 导航到IAM 在左侧菜单中&#xff0c;单击角色 。单击创建角色该按钮以创建新的 IAM 角色。 在创建角色部分&#xff0c;为角色选择可信实体类型&#xff1a; AWS 服务 使用案例:EC2 单击下一步 添加权限&#x…

LeetCode面向运气之Javascript—第2600题-K件物品的最大和-94.68%

LeetCode第2600题-K件物品的最大和 题目要求 袋子中装有一些物品&#xff0c;每个物品上都标记着数字 1 、0 或 -1 。 四个非负整数 numOnes 、numZeros 、numNegOnes 和 k 。 袋子最初包含&#xff1a; numOnes 件标记为 1 的物品。numZeroes 件标记为 0 的物品。numNegOn…

【GitOps系列】使用 ArgoCD 快速打造GitOps工作流

文章目录 ArgoCD简介ArgoCD安装访问ArgoCDGitOps 工作流总览创建 ArgoCD 应用检查 ArgoCD 同步状态访问应用 连接 GitOps 工作流体验 GitOps 工作流生产建议1&#xff09;修改默认密码2&#xff09;配置 Ingress 和 TLS3&#xff09;使用 Webhook 触发 ArgoCD4&#xff09;将源…

【C++】开源:Boost网络库Asio配置使用

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍Asio网络库配置使用。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;下次…