kindEditor官网:http://kindeditor.net/demo.php

个人实践:

为了在自己的项目中引入一个类似用户写博客的功能,在网上找到了kindeditor,真心又好又易用。

一、准备工作

1、下载kindeditor,在官网上点击右上方的下载链接,我下载的是4.1.11版。由于我的项目前端采用jsp,所以将解压以后的asp,asp.net和php文件夹删掉。

在jsp文件夹里的就是在jsp下使用kindeditor的demo。需要注意的是,demo.jsp文件中有笔误,需要首先将<script charset="utf-8" src="../kindeditor.js"></script>

的src指向kindeditor-all-min.js才可以。

2、阅读demo.jsp:kindeditor的js使用K.create方法,于页面加载完毕以后,在name是content1的textarea前面自动创建博客编辑功能toolbar,最关键的uploadJson参数指定

了用户上传图片、动画、文件等媒体文件的后台处理controller。在demo.jsp中,表单提交给了demo.jsp自己,可以在jsp代码的开头部分发现,程序从request中将content1的

内容取了出来,在body中,将内容展示在form表单之前。也就是说demo.jsp中的博客编辑器提交后的内容会在编辑器上方展示出来。需要注意的是htmlspecialchars方法,它

将html标签中的相关字符进行转义,目的是将用户提交的内容在博客编辑器中显示,方便用户继续编辑已经存在的内容。这个转义的过程在项目中我们其实是放在后台处理的,

做好以后直接传给前台展示。fileManagerJson参数指定了上传后文件的编辑界面,由于我的项目不需要这个功能,所以将这个参数舍去,将allowFileManager参数置false。

afterCreate参数指定了创建博客编辑功能toolbar以后做的事,就是当用户使用ctrl+enter的时候提交表单。我不需要这功能所以也可以舍去afterCreate。

3、阅读完了demo.jsp以后,如何展示编辑工具栏,如何提交表单,如何在编辑框中显示已经存在的内容,这几个关键的基本问题就都找到答案了,下面就是实践和解决细节问题。

主要是两个后台问题,一是如何处理uploadJson参数对应的文件上传及给kindeditor返回准确的值,二是表单提交以后如何在后台取到提交的内容,由于我使用了springmvc的form

标签库,如何结合标签库也是个小问题。

二、编码和实现

1、jsp文件片段

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>${pageTitle }</title>
<link href="/Public/media/css/new/page.css" rel="stylesheet"
type="text/css" />
<link rel="stylesheet"
href="/Public/kindeditor/themes/default/default.css" />
<link rel="stylesheet"
href="/Public/kindeditor/plugins/code/prettify.css" />
<script charset="utf-8" src="/Public/kindeditor/kindeditor-all-min.js"></script>
<script charset="utf-8" src="/Public/kindeditor/lang/zh-CN.js"></script>
<script charset="utf-8"
src="/Public/kindeditor/plugins/code/prettify.js"></script>
<script>
KindEditor.ready(function(K) {
var editor1 = K.create('textarea[name="content"]', {
cssPath : '/Public/kindeditor/plugins/code/prettify.css',
uploadJson : '${pageContext.request.contextPath}/workConfig/updateContent',
allowFileManager : false
});
prettyPrint();
});
</script>
</head>
<body>
<form:form action="${formActionURL}" method="post" commandName="work">
<div class="formDiv">
<table width="1020" border="0">
            <tr>
<td align="right">展示页面:</td>
<td align="left">
<textarea name="content" rows="20" cols="100" style="width: 700px; height: 200px; visibility: hidden;">
${work.content }
</textarea>
</td>
</tr>
          </table>
</div>
</form:form>
</body>
</html>

1.1:曾尝试过使用springmvc的textarea标签库<form:textarea,虽然只要将kindeditor的K.create里textarea的name改为<form:textarea的name即可(假设form:textarea的path值为"content",那么这个标签库在被翻译成html时,textarea的name和id会被自动赋值为"content"),但由于textarea的内容会被springmvc自动赋值给表单代表的Model类的相应值,所以htmlspecialchars的转义过程就没法进行了,当然你也可以修改JavaBean的

getContent方法中加入转义过程,但这么做稍显繁琐,不如就不用form:textarea标签库,只要将其name值设置为表单Model类的属性值,内容在提交后一样会被自动赋值给对应的属性(经试验证实)。

2、文件上传处理程序片段

   @RequestMapping(value="/updateContent",produces = "application/json; charset=utf-8")
@ResponseBody
public String updateContent(MultipartHttpServletRequest request) {
MultipartFile realMediaFile = null;
Iterator<String> iter = request.getFileNames();
JSONObject obj = new JSONObject();
while (iter.hasNext()) {
// 取得上传文件
MultipartFile file = request.getFile(iter.next());
if (file != null) {
realMediaFile = file;
}
if (realMediaFile != null) { // 定义允许上传的文件扩展名
String extStr = "gif,jpg,jpeg,png,bmp,swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb,doc,docx,xls,xlsx,ppt,htm,html,txt,zip,rar,gz,bz2";
List<String> extList = Arrays.asList(extStr.split(",")); // 最大文件大小
long maxSize = 1000000; // 准备好路径参数
String uploadMediaSavePath = pathUtil.getYgbhUploadMediaDiskFolderPath(request);
String urlRootPath = pathUtil.getYgbhUploadMediaUrlFolderPath();
List<MultipartFile> files = new ArrayList<MultipartFile>();
files.add(realMediaFile); // 保存
String message = "";
if (realMediaFile.getSize() > maxSize) {
message = "上传文件大小超过限制。";
}
String originalfileName = realMediaFile.getOriginalFilename();
String suffixName = originalfileName.substring(originalfileName.lastIndexOf(".") + 1).toLowerCase();
if (!extList.contains(suffixName)) {
message = "上传文件扩展名是不允许的扩展名。\n只允许[" + extStr + "]格式。";
}
String newFileName = "";
try {
newFileName = MultipartFileUtil.saveMediaFiles(files, uploadMediaSavePath, urlRootPath).get(0);
} catch (Exception e) {
message = "上传文件失败。";
}
try {
if (!message.isEmpty()) {
obj.put("error", 1);
obj.put("message", message);
} else {
obj.put("error", 0);
obj.put("url", urlRootPath + newFileName);
}
} catch (Exception e) {
log.error("上传文件[" + originalfileName + "]失败。");
e.printStackTrace();
}
} else {
try {
obj.put("error", 1);
obj.put("message", "找不到文件。");
} catch (JSONException e) {
log.error("上传文件失败。");
e.printStackTrace();
}
}
return obj.toString();
}
return obj.toString();
}

2.1:使用@ResponseBody的返回值为String类型的方法,在试验后被证明是可以使用的。如果不标识@ResponseBody,返回String类型的Controller方法会将返回值视为jsp文件的路径去寻找jsp文件。而如果你打算

将返回值类型用某JavaBean来代替,心想反正使用了@ResponseBody,springmvc会将对象转换成正确的JSON格式,结果是kindeditor拿不到返回值。

2.2:由于kindeditor生成的博客编辑工具栏有批量上传按钮,所以在取得用户提交内容时,需要用iterator的方式。

2.3:看到urlRootPath变量了吗,它指向我的系统的静态资源工程,是一个只能在本系统内可以访问的不跨域url。这也牵扯到后面的一个问题。需求是:用户自己编写的博客内容,会以html的方式保存在系统的数据库中,

该段html代码必须在它被从数据库里取出并放置在一个html页面的body片段中时能够完整地展示所有内容,包括图片、动画等媒体资源内容。那么问题来了,无论我怎么设置,就算是我直接在urlRootPath前拼接“http://

XXX.XXX.XX.XX:8080”,等到内容显示在textarea编辑框中时,图片等媒体资源的src依然被kindeditor自动改为不跨域的url,也就是说,只能在系统内展示时才能看见这些非文本的内容。如何优雅地解决该问题我至今

还没找到很好的办法,只是暂时在保存博客内容html时,将所有包含不跨域url的内容前面自动加上类似“http://XXX.XXX.XX.XX:8080”的前缀,以保证该资源在任何地方都能被访问。

补充,上面划线部分的问题已经得到解决(参考资料:http://www.111cn.net/wy/255/64719.htm),给KindEditor加一个与uploadJson同级别的运行参数,urlType:'domain',

urlTypeY有四种值,""表示不修改URL,"relative"表示相对路径,"absolute"表示绝对路径,"domain表示带域名的绝对路径"。

由于该问题已解决,所以3中的replace过程可以去掉了。

2.4:produces = "application/json; charset=utf-8"这句如果不加,返回的中文内容会是乱码。

3、表单提交内容处理程序片段

@RequestMapping(value = "/editWork", method = RequestMethod.POST)
public ModelAndView editWork(@Valid @ModelAttribute("work") DesignerWorks work, BindingResult br,
HttpServletRequest request) {
ModelAndView mv = new ModelAndView();
mv.addObject("work", work);
if (br.hasErrors()) {
mv.addObject("currentMenuDesc", "当前目录:首页>系统管理>作品管理>编辑作品");
mv.addObject("backToURL", request.getContextPath() + "/workConfig/openWorkConfig");
mv.addObject("formActionURL", request.getContextPath() + "/workConfig/editWork");
mv.addObject("pageTitle", "编辑作品");
mv.setViewName("editWork");
} else {
try {
DesignerWorks workToSave = work;
workToSave.setContent(workToSave.getContent().replace(pathUtil.getServerUrl(request), ""));
workToSave.setContent(workToSave.getContent().replace(pathUtil.getUploadMediaRootUrl(),
pathUtil.getServerUrl(request) + pathUtil.getUploadMediaRootUrl()));
designerService.updateWork(work);
} catch (Exception e) {
mv.addObject(ConstantsUtil.ERROR_STACK, ExceptionUtils.getStackTrace(e));
mv.setViewName("error");
return mv;
}
mv.addObject(ConstantsUtil.BACK_TO_URL, request.getContextPath() + "/workConfig/openWorkConfig");
mv.setViewName("success");
}
return mv;
}

3.1:可以看到媒体文件url的replace的过程,getServerUrl的代码片段如下:


import java.io.File;
import java.net.InetAddress;

import javax.servlet.http.HttpServletRequest;

public static String getServerUrl(HttpServletRequest request) throws Exception{
return "http://"+InetAddress.getLocalHost().getHostAddress()+":"+request.getServerPort();
}

三、补充

1、问题:在之后的项目中,我使用了jquery.easyui.min.js的.form()来间接提交表单,发现由kindeditor生成的textarea内容始终无法被后台接收到。

2、调查:查看页面源码我发现,kindeditor工作时,是在被它修饰的textarea的上方加了一个div,用户输入的所有内容其实都是在编辑div中的内容而不是直接写在textarea里,

当用户使用传统方式提交表单时,kindeditor一定是自动有一个将用户输入内容粘贴入textarea的动作,而当使用js间接提交表单时,kindeditor的这个自动的动作没有被触发,所以

后台得到的是还未被粘贴内容的textarea的文本。

3、解决:最直接的想办法是手动调一下这个自动粘贴的程序。搜索了一下发现已有人解决。http://lxy.me/ajax-kindeditor-content-to-textarea.html

<script type="text/javascript">
KindEditor.ready(function(K){
K.create('textarea[name="content"]', {
themeType: 'simple',
resizeType: 1,
uploadJson: 'common/KEditor/upload_json.php',
fileManagerJson: 'common/KEditor/file_manager_json.php',
allowFileManager: true,
//下面这行代码就是关键的所在,当失去焦点时执行this.sync(),同步输入的值到textarea中;
afterBlur: function(){this.sync();}
});
});
</script>

使用springmvc,jsp,结合网页文本编辑器kindEditor实现基本博客编辑功能的更多相关文章

  1. python 全栈开发,Day83(博客系统子评论,后台管理,富文本编辑器kindeditor,bs4模块)

    一.子评论 必须点击回复,才是子评论!否则是根评论点击回复之后,定位到输入框,同时加入@评论者的用户名 定位输入框 focus focus:获取对象焦点触发事件 先做样式.点击回复之后,定位到输入框, ...

  2. easyUI整合富文本编辑器KindEditor详细教程(附源码)

    原因 在今年4月份的时候写过一篇关于easyui整合UEditor的文章Spring+SpringMVC+MyBatis+easyUI整合优化篇(六)easyUI与富文本编辑器UEditor整合,从那 ...

  3. 富文本编辑器 KindEditor 的基本使用 文件上传 图片上传

    富文本编辑器 KindEditor 富文本编辑器,Rich Text Editor , 简称 RTE , 它提供类似于 Microsoft Word 的编辑功能. 常用的富文本编辑器: KindEdi ...

  4. 富文本编辑器kindeditor配置

    <!--富文本编辑器kindeditor配置↓ --> <link type="text/css" rel="stylesheet" href ...

  5. 后台文本编辑器KindEditor介绍

    后台文本编辑器KindEditor介绍 我们在自己的个人主页添加文章内容的时候,需要对文章内容进行修饰,此时就需要文本编辑器助阵了! 功能预览 KindEditor文本编辑器 KindEditor文本 ...

  6. Django配置富文本编辑器kindeditor

    一.简介 django是一个容易快速上手的web框架,用它来创建内容驱动型的网站(比如独立博客)十分方便.遗憾的是,django并没有提供官方的富文本编辑器,而后者恰好是内容型网站后台管理中不可或缺的 ...

  7. springMVC -- 整合UEditor(富文本编辑器)

    工作中需要用到UEditor编辑文本,在与springMVC进行整合时,出现了一些问题,结果导致,在进行图片上传时出现如下提示: 上网查询了很多相关资料,此处简要记录下,防止以后遇到类似问题. 一种方 ...

  8. JAVAEE——宜立方商城04:图片服务器FastDFS、富文本编辑器KindEditor、商品添加功能完成

    1. 学习计划 1.图片上传 a) 图片服务器FastDFS b) 图片上传功能实现 2.富文本编辑器的使用KindEditor 3.商品添加功能完成 2. 图片服务器的安装 1.存储空间可扩展. 2 ...

  9. django-应用中和amdin使用富文本编辑器kindeditor

    文章描述.新闻详情和产品介绍等,都需要大量的文字描述信息或图片.视频.文字的编辑等,这个时候我们就需要介绍第三方富文本编辑器. 今天介绍的是django中绑定和应用kindeditor编辑器: 效果如 ...

随机推荐

  1. 常用Git命令清单(转)

    文/阮一峰 我每天使用 Git ,但是很多命令记不住. 一般来说,日常使用只要记住下图 6 个命令,就可以了.但是熟练使用,恐怕要记住 60-100 个命令. 下面是我整理的常用 Git 命令清单.几 ...

  2. python 文件 IO 操作

    Python 的底层操作 * 其实Python的文件IO操作方法,和Linux底层的差不多 打开 f = open(filename , "r") 后面的 "r" ...

  3. SD卡镜像烧写--树莓派为例

    SD烧写镜像都要先擦除SD卡内容,然后用image烧写工具烧写镜像. SD卡标准官网:www.sdcard.org,提供标准的擦除工具sdformatter. windows下镜像烧写工具可选用Win ...

  4. ajax 多个参数问题,如何既能表单序列化获取,又能加参数,加全部代码

      $.param({'address':address,'delivity':delivity,'payment':payment}) + '&' + $('#card_form').ser ...

  5. Android studio3.1的XML布局文件没有自动提示不全代码功能

    将studio从2.3升级到3.1,打开后发现布局文件没有代码提示 尝试了网上一些解决方法,但发现并不是平时所说的省电模式开关的问题,也尝试了删除idea和iml文件后rebuild的方法,无效 然后 ...

  6. 安卓程序代写 网上程序代写[原]C语言基础

    C 作者:han1202012 发表于2013-11-1 19:53:29 原文链接 阅读:28 评论:0 查看评论

  7. 【转】接口测试Session/Cookie笔记(二)

    Windows系统运行计算器命令:calc python显示上一步操作命令:Alt+p python显示上一步操作结果:_(英文下划线) Session是存放在服务器的键值对 ,用于保存客户端的某个特 ...

  8. 8个日志级别(OFF、FATAL、ERROR、WARN、INFO、DEBUG、TRACE、 ALL)

    log4j定义了8个级别的log(除去OFF和ALL,可以说分为6个级别),优先级从高到低依次为:OFF.FATAL.ERROR.WARN.INFO.DEBUG.TRACE. ALL. ALL 最低等 ...

  9. php命令行脚本 mock数据

    <?php $con = mysql_connect("192.168.1.5:3306","root","123"); if (!$ ...

  10. Opengl绘制我们的小屋(二)第一人称漫游

    这章我们先讲第一人称漫游的实现.在openTK里,我们用函数Matrix4.LookAt(caram.Eye,caram.Target,Vector3.UnitY)来放置摄像机,其中三个参数分别与摄像 ...