summernote富文本编辑器有插入图片功能,不过默认使用base64数据URL,这就导致了整个文本内容特别长,加入一两张图片后就超出了mysql的text存储类型所能容纳的最大长度。
正常情况下,存储带图的文章时只需要携带图片的URL就行了,图片存在服务器的某个文件夹中,而不是直接存储到数据库。
好在summernote支持重写回调函数,下面是代码:
JSP:
<script>
$(document).ready(function () {
$('.summernote').summernote({
callbacks: {//回调函数,重写onImageUpload方法
onImageUpload: function (files) {
sendFile(this, files[0]);
}
}
})
});
</script>
<%--summernote上传文件--%>
<script>
function sendFile(val, files) {
data = new FormData();
data.append("file", files);
$.ajax({
data: data,
dataType: 'json',
type: "POST",
url: "/blog/uploadFile",
cache: false,
contentType: false,
processData: false,
responseType: "json",
success: function (data) {
$('#updateText').summernote('insertImage','http://localhost:8080/MckfFile/'+data.fileName);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(XMLHttpRequest.status);
alert(XMLHttpRequest.readyState);
alert(textStatus);
}
});
}
</script>
Controller:
@RequestMapping("/uploadFile")
@ResponseBody
public Map<String,Object> handleFile(HttpServletRequest request,@RequestParam("file") MultipartFile file) throws IOException{
String path="E:\\MckfFile";
String fileName=file.getOriginalFilename();
String uuid= UUID.randomUUID().toString().replace("-","");
fileName=uuid+"_"+fileName;
file.transferTo(new File(path,fileName));
Map<String,Object> map =new HashMap<String, Object>();
map.put("fileName",fileName);
return map;
}
总体思路:
在浏览器中选择完图片之后,将图片上传到服务器并返回图片的URL,如果上传成功就能在页面上直接看到插入的图片。因为选择完图片不一定会保存文章,可能用户会选择离开页面,这时候就要在服务端删掉之前上传的图片。(这部分功能我还没做)
遇到的问题:
一开始在上传完图片之后能够在服务器里看到图片,但是无法在页面的编辑框内看到图片,选择code view也完全找不到图片的踪迹。这个问题很奇怪,我一开始以为是summernote的问题,去官方文档查看了API,确认这部分代码是没问题的。
逐步排查后我发现是我服务器端图片存储路径的问题,我将图片存储路径设置在了webapp内部,服务器接受到图片之后并没有马上更新资源文件,因此页面无法通过URL访问到这张图片,需要重启tomcat才能正确访问。
我设置tomcat为热更新,无效。
以为是延时的问题,令Controller延迟返回10秒,还是无效。
这个问题就很难受了,总不能每次上传图片后就重启服务器吧,
或许可以在文章中用特殊的字符替换掉图片的url,在用户将文章提交到服务端时,再由服务端对文章里的特殊字符进行处理,更换为对应的图片URL,这个方法实现起来并不难,不过问题是用户无法在上传图片后在页面中预览图片的效果,这是很不好的体验。
然后我发现了一篇文章,更改图片存储的路径为项目外的文件夹,这样访问时就不用每次都关心资源文件是否有更新了。
如图所示,在idea打开Tomcat的设置,点击右边的加号,选择本地电脑中存放图片的那个文件夹,与tomcat关联之后就可通过localhost:8080/MckfFile/xxxxx.png 访问到所需要的文件了,不需要更新tomcat。
Controller代码中还用到了uuid函数,这是用来生成随机字符码作为存储的图片前缀,防止上传重名图片后在读文件时出现未知情况。