富文本编辑器CKEditor配置与使用

富文本编辑器CKEditor配置与使用

起因

因为这学期 Java Web 大作业项目选的是在线新闻发布系统,有在线编辑器的需求,所以有了这篇文章。

最开始选的是 Markdown 编辑器,但又想了想,Markdown好想不怎么合适,因为对于编辑新闻来说,主要就是排版和图片这些,而且对于不擅长Markdown语法的编辑者更是十分困难去编写新闻,与Markdown相比,富文本更适合这个需求,它就像一个在线的Word,只需要操作上方的按钮即可完成简单的排版工作。

开始

放弃了 Editor.md 的Markdown编辑器,转向了 CKEditor 的富文本编辑器,之后便是搜索各种资料,再加上官方文档,已完成CKEditor的配置。

参考

CKEditor5基本使用

富文本编辑器CKEditor配置及使用

CKEditor 4.12.1富文本编辑器的配置与使用(详细版)

CKEditor实现图片上传

CKEditor已升级到5.x以上的版本了,可能是因为版本较新,使用和写教程配置的不多,可参考的并不多,而且在阅读官方文档遇到很多困难,就我的感觉是,5以上版本给使用者自由度很大,因此配置也较复杂多样。

搞了很久之后终于放弃了版本5,最终选择的是版本4.8,上面参考链接对我帮助最大的是第二的和第三个。

下载官方js文件

进入官网点击Release notes选择4.8.0版本点击Download.Zip下载

备注:目前最新版本4.9.0有bug,所以用4.8.0版本

官网

访问官网有点慢,耐心等待就好

官方js解压后复制到项目中,引入CKEditor的js文件

<script src="${pageContext.request.contextPath}/Static/js/lib/ckEditor/ckeditor.js"></script>

页面中使用CKEditor

<!--在需要使用编辑器的地方插入textarea标签 -->
内容:<textarea name="content" id="content"></textarea>
<!--将相应的控件替换成编辑器代码 若想要自定义高度加入{height:"xxx"} -->
<script type="text/javascript">
    window.onload = function () {
        CKEDITOR.replace('content', {height: "475px"});
    };
</script>

示例:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
    <title>edit</title> 
    <script src="${pageContext.request.contextPath}/Static/js/lib/ckEditor/ckeditor.js"></script>
    <script type="text/javascript">
        window.onload = function () {
            CKEDITOR.replace('content', {height: "475px"});
        };
    </script>   
</head>
<body>
    <form method="post" action="${pageContext.request.contextPath}/addNews" onsubmit="">
        <input name="user_id" type="hidden" value="${sessionScope.user.user_id}"/>
        标题:<input type="text" name="title" id="title"/><br/>
        类别:<select name="category_id">
        <c:forEach items="${requestScope.categorys}" var="category">
            <option value="${category.category_id}">${category.category_name}</option>
        </c:forEach>
    </select><br/>
        内容:<textarea name="content" id="content"></textarea>
        <input name="state" type="hidden" value="0"/>
        <input type="submit" value="发布"/>
    </form>
</body>
</html>

效果展示:

新闻编辑

后台取值:

    @RequestMapping("addNews")
    public String addNews(News news) {......}

图片上传

  • 清空图像预览框中的文字

原始图像上传

找到项目下的ckeditor文件夹下的config.js中添加:

    config.image_previewText=' ';

效果如下:

  • 配置上传图片请求地址

接着上面config.js中添加:

    config.filebrowserUploadUrl="/xxx/uploadImage";

参考的文章里都说了,这里还需要回传一段js脚本:

        out.println("<script type=\"text/javascript\">");
        String callback = request.getParameter("CKEditorFuncNum");
        out.println("window.parent.CKEDITOR.tools.callFunction(" + callback+ ",'" + imageContextPath + "','')");
        out.println("</script>");

有了这段代码,图片上传成功后,由你设置的上传地址 + filename(自己可设定)相对地址,就可以使用这个图片,直接转到“图像”页面。这时可以对图片大小等进行修改。

上传预览

点击确定后编辑器如下:

上传成功并显示

  • 上传的图片重新显示到页面
<form method="post" action="${pageContext.request.contextPath}/updateNews">
    <input name="news_id" type="hidden" value="${requestScope.news.news_id}">
    <input name="user_id" type="hidden" value="${sessionScope.user.user_id}"/>
    标题:<input type="text" name="title" id="title" value="${requestScope.news.title}"/><br/>
    类别:<select name="category_id">
    <c:forEach items="${requestScope.categorys}" var="category">
        <option value="${category.category_id}"
                <c:if test="${category.category_id==requestScope.news.category_id}">
                    selected="true"
                </c:if>>${category.category_name}</option>
    </c:forEach>
</select><br/>
    内容:<textarea name="content" id="content">${news.content}</textarea>
    <input name="state" type="hidden" value="${news.state}"/>
    <input type="submit" value="修改"/>
</form>
  • 我的后台上传代码
/**
 * @ClassName: ImageUploadUtil
 * @Description: 图片上传工具类,包括ckeditor操作
 * created by Vinne.WU
 * 2019.7.17 14:27
 */
public class ImageUploadUtils {
    // 图片类型
    private static List<String> fileTypes = new ArrayList<String>();

    static {
        fileTypes.add(".jpg");
        fileTypes.add(".jpeg");
        fileTypes.add(".bmp");
        fileTypes.add(".gif");
        fileTypes.add(".png");
    }

    /**
     * 图片上传
     *
     * @param request
     * @param DirectoryName
     * @return
     * @throws IllegalStateException
     * @throws IOException
     * @Title upload
     */
    public static String upload(HttpServletRequest request, String DirectoryName) throws IllegalStateException,
            IOException {
        // 创建一个通用的多部分解析器
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
        // 图片名称
        String fileName = null;
        // 判断 request 是否有文件上传,即多部分请求
        if (multipartResolver.isMultipart(request)) {
            // 转换成多部分request
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
            // 取得request中的所有文件名
            Iterator<String> iter = multiRequest.getFileNames();
            while (iter.hasNext()) {
                // 记录上传过程起始时的时间,用来计算上传时间
                long pre =System.currentTimeMillis();
                // 取得上传文件
                MultipartFile file = multiRequest.getFile(iter.next());
                if (file != null) {
                    // 取得当前上传文件的文件名称
                    //String myFileName = file.getOriginalFilename();
                    String oFileName=file.getOriginalFilename();
                    //时间命名图片
                    String myFileName=Long.toString(pre)+oFileName.substring(oFileName.lastIndexOf("."));
                    System.out.println(myFileName);
                    // 如果名称不为“”,说明该文件存在,否则说明该文件不存在
                    if (myFileName.trim() != "") {
                        // 获得图片的原始名称
                        String originalFilename = file.getOriginalFilename();
                        // 获得图片后缀名称,如果后缀不为图片格式,则不上传
                        String suffix = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();
                        if (!fileTypes.contains(suffix)) {
                            continue;
                        }
                        // 获得上传路径的绝对路径地址(/upload)-->
                        String realPath = request.getSession().getServletContext().getRealPath("/" + DirectoryName);

                        System.out.println(realPath);
                        //String realPath=request.getContextPath()+"/Static/img" ;
                        // 如果路径不存在,则创建该路径
                        File realPathDirectory = new File(realPath);
                        if (realPathDirectory == null || !realPathDirectory.exists()) {
                            realPathDirectory.mkdirs();
                        }
                        // 重命名上传后的文件名 111112323.jpg
                        fileName = myFileName;
                        // 定义上传路径 .../upload/111112323.jpg
                        File uploadFile = new File(realPathDirectory + "/" + fileName);
                        System.out.println(uploadFile);
                        file.transferTo(uploadFile);
                    }
                }
            }
        }
        return fileName;
    }

    /**
     * ckeditor文件上传功能,回调,传回图片路径,实现预览效果。
     *
     * @param request
     * @param response
     * @param DirectoryName
     * @throws IOException
     * @Title ckeditor
     */
    public static void ckeditor(HttpServletRequest request, HttpServletResponse response, String DirectoryName)
            throws IOException {
        String fileName = upload(request, DirectoryName);
        // 结合ckeditor功能
        // imageContextPath为图片在服务器地址,如upload/123.jpg,非绝对路径
        String imageContextPath = request.getContextPath() + "/" + DirectoryName + "/" + fileName;
        System.out.println(request.getContextPath());
        System.out.println(DirectoryName);
        System.out.println(fileName);

        //构建json回调消息
        PrintWriter out=response.getWriter();
        // 返回"图像"选项卡并显示图片  request.getContextPath()为web项目名
        out.println("<script type=\"text/javascript\">");
        String callback = request.getParameter("CKEditorFuncNum");
        out.println("window.parent.CKEDITOR.tools.callFunction(" + callback
                + ",'" + imageContextPath + "','')");
        out.println("</script>");
        out.flush();
        out.close();
    }
}

因为我的最终大作业是SSM框架的所以在配置SpringMVC是要加入:

    <!-- 定义文件上传解析器 -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- 设定默认编码 -->
        <property name="defaultEncoding" value="utf-8" />
        <!-- 设定文件上传的最大值为10M,单位B,10*1024*1024 -->
        <property name="maxUploadSize" value="10485760" />
        <!-- 设定文件上传时写入内存的最大值,如果小于这个参数不会生成临时文件,默认为10240 -->
        <property name="maxInMemorySize" value="40960" />
    </bean>

使用过程中发现上传含中文图片回显会有问题,js代码传中文不行,所以将就把图片命名为

System.currentTimeMillis();

这样也能避免上传图片名称一样时覆盖问题,不过一定程度上会导致用户同一时间点上传图片覆盖,不过这个几率挺小的,毕竟毫秒单位啊。

最后分享“java 获取HTML文本IMG标签的src地址”

参考

    /**
     * 获取HTML文件里面的IMG标签的SRC地址
     * @param htmlText 带html格式的文本
     */
    public static List<String> GetHtmlImageSrcList(String htmlText)   
    {
        List<String> imgSrc = new ArrayList<String>();
        Matcher m = Pattern.compile("src=\"?(.*?)(\"|>|\\s+)").matcher(htmlText);
        while(m.find())
        {    
            imgSrc.add(m.group(1));
        }
        return imgSrc;
    }
    
    /**
     * 去掉所有的HTML,获取其中的文本信息 
     * @param htmlText
     * @return
     */
    public static String GetHtmlText(String htmlText)   
    {
        String regEx_html = "<[^>]+>"; // 定义HTML标签的正则表达式 
        Pattern p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE);  
        Matcher m_html = p_html.matcher(htmlText);
        htmlText = m_html.replaceAll(""); // 过滤HTML标签
        return htmlText;
    }

这次分享结束

再次强调这是个人学习记录,谈不上教程

  • 2
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无奈何杨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值