最近项目中可能要支持markdown 编辑器,所以提前调研了一下;现在基本做技术的没有不知道Markdown 的,因为实在是太强大了,只需要了解很简单的几个操作,即可编辑非常优美的文章,包括TeX科学公式(基于KaTeX)、流程图 Flowchart 和 时序图 ,不在让你浪费时间在格式的调整。
资源:Editor.md https://pandao.github.io/editor.md/
这个插件就不多说了,以为官网已经说的很多了,虽然在使用上有点小瑕疵,但是大体上还是很不错的,即插即用。
这边需要说明一下 editor.md目录,本文介绍的版本为v1.5.0,在首页下载完成,解压editor.md-master.zip文件,可以看到如下图的目录结构:
图中红色框内是我们要引用到项目的文件和目录。
导入到web 项目中的目录如下:
红线框内 fonts,images,lib,plugins 目录是从解压的文件中原封不动拷贝过来的,尽量不改动(文件夹名字),因为后面如果要引入会出现奇葩的问题。
红线框内js,css 文件,我只拷贝了editormd.js,editormd.css
在使用到editor.md的页面引入css和js:
在需要添加editor.md编辑器的地方输入以下div:
注意:此处需要注意的是,无论需要html格式的内容还是markdown格式的内容,都只需要写一个textarea。此处有一个很大的坑。不少其他教程中说需要两个textarea,那么会导致后一个textarea后台获得的数据是一个数组,而不是单纯的HTML内容。
js代码用来将上面的textarea进行渲染:
此段js代码中的content-editormd就是上面div的id。
path路径需要指定到项目中对应的lib的路径。如果设置不对markdown 无法渲染出来。
saveHTMLToTextarea设置为true表示,转化为html格式的内容也同样提交到后台。
好,到这边你就可以看到页面效果了。如下:
editor.md的上传图片功能实现起来比较简单,只需要在上段代码中再添加一些配置即可。
这个时候,你就可以看到,但你点击工具栏上“添加图片” 的时候。 效果如下:
但是,当你点击“本地上传” 后,发现没有任何反映。图片地址也没有回填;我第一反应是是不是我参数设置有问题啊,但是,经过我看demo 包括,上git 讨论区查看此类问题的时候,并没有,就只需要设置imageUpload,imageFormats,imageUploadURL 三个参数即可,除非跨域了;但是我的情况并没有跨域啊,所以我打开查看页面的调试模式,看到了一个错,报;如图:
这尼玛什么情况。。。;完全摸不着头脑。
再到后台一看,已经报错。
意思就是,后台接口中声明了MultipartFile ,所以必须要加入:
commons-io
commons-io
2.2
commons-fileupload
commons-fileupload
1.3.2
同时必须在spring-web.xml 中加入,注意:id 必须是multipartResolver
5242880
然后重启一下,再次点击“本地上传”,
已经可以了。
到了这一步,我们再来深究一下这个弹框,本地上传到底做了什么,看看源码来。贴上源码
一看,这他娘什么啊,从uploadIframe获取内容 ,还解析,把url 赋值到data-url 上;这是什么鬼啊,再回去看看创建这个dialog 做了哪些事情。
看到这边,恍然大悟没有。。。,
原来它在这个“本地上传”按钮 做的事情,不仅仅是选取了本地的图片资源,而且还请求上传到服务后端了,而且表单提交是在iframe 里面执行的,所以才有了上面解析iframe 内容的代码,如果后端没有反应,或者返回的格式有问题,你就根本不知道发生了什么了,哎,坑。教程也没有说明一下。
特地说明一下:后端返回的报文必须json 格式:
{
success : 0 | 1, //0表示上传失败;1表示上传成功
message : "提示的信息",
url : "图片地址" //上传成功时才返回
}
0,1 必须是数字;
url :就是你图片存在的地址,这个就是返回到弹框中的图片地址。
这边附上后端上传图片代码:
@Controller
@RequestMapping("/file")
public class FileUploadController {
private static final Logger LOGGER = LoggerFactory.getLogger(FileUploadController.class);
private static final String IMAGE_URL_PRE ="http://access-usf.jd.com:8089/file/viewImage?key=";
@Resource
private MessageStoreService messageStoreService;
@ResponseBody
@RequestMapping("/uploadImage")
public String uploadImage(HttpSession session, @RequestParam(value = "editormd-image-file") MultipartFile file) {
LOGGER.info("========================上传图片开始=========================");
JSONObject res = new JSONObject();
try {
byte[] fileByte = file.getBytes();
String fileName = file.getOriginalFilename();
String key = messageStoreService.saveBytes(fileByte);
if(StringUtils.isNotEmpty(key)){
res.put("success", 1);
res.put("message", "上传成功");
res.put("url",IMAGE_URL_PRE+key);
} else {
res.put("success", 0);
res.put("message", "上传失败" );
}
} catch (Exception e) {
LOGGER.error("上传图片异常", e);
res.put("success", 0);
res.put("message", "上传异常");
}
LOGGER.info("上传图片返回结果:{}", res);
return res.toString();
}
/**
在线预览图片
*/
@RequestMapping("/viewImage")
@ResponseBody
public void viewImage(HttpServletRequest request, HttpServletResponse response, String key){
BufferedInputStream bis = null;
OutputStream os = null;
response.setContentType("text/html; charset=UTF-8");
response.setContentType("image/jpeg");
byte[] file = messageStoreService.loadBytes(key);
try {
os = response.getOutputStream();
os.write(file);
os.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (os != null){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bis != null){
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
好辣,看一下效果。
已经上传成功了。。。