背景
项目有站内信的开发,考虑富文本编辑框的使用。在ckeditor和ueditor两兄弟中选择了ckeditor,看起来简洁清爽些。
ckeditor汉化
官网下载的ckeditor默认是英语版,需要做汉化切换。切换步骤如下:
-
下载node和yarn 工具;
-
.创建目录 clone下ckeditor的源码;.创建目录 clone下ckeditor的源码;
git clone -b stable https://github.com/ckeditor/ckeditor5-build-classic.git cd ckeditor5-build-classic npm install
-
修改 src/ckeditor.js && webpack.config.js 的language为zh-cn;
-
重新构建ckeditor;
yarn run build
-
构建完成后,将build 下的ckeditor.js && ckeditor.js.map 拷贝到项目即可。
图片上传
原理
- 拖拉,选择,粘贴图片显示在编辑框; 向图片服务器发起请求,
- 上传图片;
- 上传完成用服务器返回的链接替代编辑框的图片信息
解决方案
(1):使用CKEditor自带云服务,图片上传到CKEditor服务器;
(2):使用ckfinder框架,在初始化CKEditor时,需要定义 ckfinder的uploadUrl参数,参数为上传到自己服务器的地址;
(3)自己写上传功能,定义UploadAdapter,实现upload()和 abort() 方法,并对UploadAdapter进行调用。
实操
前端
ClassicEditor
.create( document.querySelector( '#editor' ),{
toolbar: ["heading", "|", "alignment:left", "alignment:center", "alignment:right", "alignment:adjust", "|", "bold", "italic", "blockQuote", "link", "|", "bulletedList", "numberedList", "imageUpload", "|", "undo", "redo"],
ckfinder: {
uploadUrl: "http://localhost:8080/message/sitemail/saveImg"
}
} )
.then( editor => {
console.log( editor );
} )
.catch( error => {
console.error( error );
} );
后台
public Map<String, String> saveImg(MultipartFile file,HttpServletRequest request) {
if(file==null || "".equals(file.getOriginalFilename().trim())) {
return generateResult(false, "#");
}
String originalName = file.getOriginalFilename();
// generate file name
String localFileName = System.currentTimeMillis() + "-" + originalName;
String path = ClassUtils.getDefaultClassLoader().getResource("").getPath()+"static/upload/sitemail";
File imageDir = new File(path);
if(!imageDir.exists()) {
imageDir.mkdirs();
}
String localFilePath = path + File.separator + localFileName;
try {
file.transferTo(new File(localFilePath));
} catch (IllegalStateException e) {
e.printStackTrace();
// log here
} catch (IOException e) {
e.printStackTrace();
// log here
}
String imageContextPath = request.getContextPath() + "/upload/sitemail/" + localFileName;
// log here +
System.out.println("received file original name: " + originalName);
System.out.println("stored local file name: " + localFileName);
System.out.println("file stored path: " + localFilePath);
System.out.println("returned url: " + imageContextPath);
// log here -
return generateResult(true, imageContextPath);
}
// 以下两个字段必选,选择完图片才能正常显示
private Map<String, String> generateResult(boolean uploaded, String relativeUrl){
Map<String, String> result = new HashMap<String, String>();
result.put("uploaded", uploaded + "");
result.put("url", relativeUrl);
return result;
}