开发一个项目的时候,有一块地方突然需要使用到富文本编辑器,之前也用过一些编辑器,例如wangEditor和百度的Editior,综合来说,我更喜欢简洁型的,wangEditor就非常不错,简洁大方。百度的Editior给人看起来有种太华丽的感觉,虽然都可以配置自己需要的使用插件,但是还是喜欢wangEditor。
今天这里要说到的是wangEditor和kindEditor。
首先来说:kindEditor
下载下来后解压,解压后重命名文件夹名称为kindeditor。在Javaweb项目中如何使用,请看下图配置:
说下总体的目录结构:
- attached: 文件的上传完的存储目录。
- examples: 例子。
- jsp: 上传用到的文件。
- lang: 语言包。
- plugins: 配置插件包。
- themes: 主题目录。
再下面的就是用到的主要js文件了。
项目运行的时候记得把这几个包部署进去,包在lib目录里面。
现在可以启动tomcat,地址栏访问:http://localhost/kindeditor/kindeditor/jsp/demo.jsp
如下图是正确访问以后出现的画面:
选择插入一张图片,成功把上传完的图片显示在文本编辑器里面
最后查看一下这个图片所在的上传目录
kindeditor就说到这里,上传都配置好了,后面的怎么获取值就很好办了,这里先不说了。直接下一个编辑器。
wangEditor的使用
首先,你进入到官网,就感觉这个编辑器非常不错,简洁大方。看图所示:
直接说在项目中如何使用吧?
复制到解压后的文件到webapp目录下
这里也是整体配置开始吧:
<!-- 创建一个编辑器 -->
<script type="text/javascript">
var E = window.wangEditor
var editor = new E('#editor')
/* 获取元素 */
/* editor.customConfig.debug = location.href.indexOf('publishTask.html') > 0 */
// 限制一次最多上传 5 张图片
editor.customConfig.uploadImgMaxLength = 5
// 将图片大小限制为 3M
editor.customConfig.uploadImgMaxSize = 3 * 1024 * 1024
/* 上传图片文件的参数名称 */
editor.customConfig.uploadFileName = 'fileName'
editor.customConfig.uploadImgParams = {
//token: 'abcdef12345' // 属性值会自动进行 encode ,此处无需 encode
}
/* 图片上传的配置 */
editor.customConfig.uploadImgServer = '/stt/file/savePicture' /* 上传到服务器的,不能和base64同时使用 */
/* editor.customConfig.uploadImgShowBase64 = true */ /* base64存储 */
/* 创建 */
editor.create();
/* 上传监听函数 */
editor.customConfig.uploadImgHooks = {
before: function (xhr, editor, files) {
// 图片上传之前触发
// xhr 是 XMLHttpRequst 对象,editor 是编辑器对象,files 是选择的图片文件
alert(files)
},
success: function (xhr, editor, result) {
// 图片上传并返回结果,图片插入成功之后触发
console.log(xhr)
console.log(editor)
console.log(result)
// xhr 是 XMLHttpRequst 对象,editor 是编辑器对象,result 是服务器端返回的结果
},
fail: function (xhr, editor, result) {
// 图片上传并返回结果,但图片插入错误时触发
alert(result)
// xhr 是 XMLHttpRequst 对象,editor 是编辑器对象,result 是服务器端返回的结果
},
error: function (xhr, editor) {
// 图片上传出错时触发
// xhr 是 XMLHttpRequst 对象,editor 是编辑器对象
},
timeout: function (xhr, editor) {
// 图片上传超时时触发
// xhr 是 XMLHttpRequst 对象,editor 是编辑器对象
},
// 如果服务器端返回的不是 {errno:0, data: [...]} 这种格式,可使用该配置
// (但是,服务器端返回的必须是一个 JSON 格式字符串!!!否则会报错)
customInsert: function (insertImg, result, editor) {
// 图片上传并返回结果,自定义插入图片的事件(而不是编辑器自动插入图片!!!)
// insertImg 是插入图片的函数,editor 是编辑器对象,result 是服务器端返回的结果
// 举例:假如上传图片成功后,服务器端返回的是 {url:'....'} 这种格式,即可这样插入图片:
var url = result.url
insertImg(url)
// result 必须是一个 JSON 格式字符串!!!否则报错
}
}
<!-- 获取值 -->
document.getElementById('save').addEventListener('click', function () {
var content = editor.txt.text();
var title = $('input[name=title]').val();
var description = $('input[name=description]').val();
var score = $('input[name=score]').val();
if(title == '' || title == null){
alert('请输入标题');
return false;
}
if(description == '' || description == null){
alert('请输入任务简述信息');
return false;
}
if(content =='' || content == null){
alert('请输入内容信息');
return false;
}
if(score =='' || score == null){
alert('请输入积分设置数');
return false;
}else{
$('input[name=content]').val(content); //给隐藏表单域赋值
$.post('../../task/saveTask',$('form').serialize(),function(res){
alert(res)
});
}
}, false);
</script>
前端代码粘贴到上面了,这里说上传那块儿的。
- 首先你的配置你的上传服务器的请求地址.
- 对上传按需做一些基本配置,如:同时上传图片的数量,大小限制,文件参数名称等。
- 配置好上传事件监听,成功了..失败了...上传图片但图片未返回报错等等事件最好都监听一下。
- 返回格式的要求。官方提供了两种。
第一种:
{
// errno 即错误代码,0 表示没有错误。
// 如果有错误,errno != 0,可通过下文中的监听函数 fail 拿到该错误码进行自定义处理
errno: 0,
// data 是一个数组,返回若干图片的线上地址
data: [
'图片1地址',
'图片2地址',
'……'
]
}
第二种:
// 如果服务器端返回的不是 {errno:0, data: [...]} 这种格式,可使用该配置
// (但是,服务器端返回的必须是一个 JSON 格式字符串!!!否则会报错)
customInsert: function (insertImg, result, editor) {
// 图片上传并返回结果,自定义插入图片的事件(而不是编辑器自动插入图片!!!)
// insertImg 是插入图片的函数,editor 是编辑器对象,result 是服务器端返回的结果
//这里说的就是第二种的情况(但是感觉第二种只能单张图传,有点麻烦,第一种能多图传。)
// 举例:假如上传图片成功后,服务器端返回的是 {url:'....'} 这种格式,即可这样插入图片:
var url = result.url
insertImg(url)
// result 必须是一个 JSON 格式字符串!!!否则报错
}
}
好了,既然第一种要返回json格式,那就直接看后台代码吧。
这里是上传的请求控制器
@ResponseBody
@RequestMapping(value="savePicture",method=RequestMethod.POST)
public JSONObject savePicture(@RequestParam("fileName") MultipartFile[] fileName,
HttpServletRequest request){
JSONObject obj = new JSONObject();
//测试上传是否成功前写死的例子
// String img[] = {"http://localhost/stt/file/image/1706231708000014/2017062317080001465502.jpg/true",
// "http://localhost/stt/file/image/1706211120000005/2017062111200000589174.jpg/true",
// "http://localhost/stt/file/image/1706191036000002/2017061910360000275916.png/true"};
try {
String[] img = saveImgFiles(fileName);
obj.put("errno", 0);
obj.put("data", img);
}catch (Exception e) {
obj.put("errno", -1);
obj.put("data", "上传失败!");
e.printStackTrace();
}
System.out.println(obj);
return obj;
}
再就是保存多张图片的方法
/**
* 保存多张图片
* @param product
* @param detailImgFiles
* @throws IOException
* @throws FileNotFoundException
*/
public String[] saveImgFiles(MultipartFile[] detailImgFiles) throws FileNotFoundException, IOException{
StringBuffer sb = new StringBuffer(50);
List<String> str = new ArrayList<>();
for (int i = 0; i < detailImgFiles.length; i++) {
MultipartFile file = detailImgFiles[i];
if("".equals(file.getOriginalFilename())){
continue;
}
// StringBufferUtil.append(sb,managerConf.getProductSave(),"/");
sb.append("/base/stt/img/");
FileUtil.createDirNotExists(sb.toString());
String newFileName = newFileName(file); //重命名文件
sb.append(newFileName);
str.add("/stt/file/image/" + newFileName +"/"); //访问图片输出流的前缀地址 + //图片存储的物理路径地址。
//保存文件
FileUtil.saveFile(detailImgFiles[i].getInputStream(), new FileOutputStream(sb.toString()));
StringBufferUtil.clear(sb);
}
String[] img = (String[])str.toArray(new String[str.size()]);
return img;
}
给文件重命名方法
/**
* 给文件重新命名
* @param minImgFile
* @return
*/
private static String newFileName(MultipartFile minImgFile){
String filename = minImgFile.getOriginalFilename();
String dateStr = DateUtil.getDateStr(new Date(), "yyyyMMddHHmmsssss");
StringBuffer sb = new StringBuffer(20);
sb.append(filename);
filename = sb.replace(0, filename.lastIndexOf("."),"").toString();
StringBufferUtil.clear(sb);
sb.append(dateStr);
for (int i = 0; i < 5; i++) {
sb.append( (int)(Math.random() * 10));
}
sb.append(filename);
return sb.toString();
}//end newFileName
还有一个地方需要注意的就是文件上传到的是外部磁盘目录,我们给返回的图片要让它访问磁盘目录文件,需要用文件输出流:
/**
* 访问一个添加的图片
* @param fileName
* @param request
* @return
*/
@RequestMapping("/image/{fileName}/")
public void visitImg(@PathVariable("fileName") String fileName,HttpServletResponse response){
FileInputStream fis = null;
StringBuffer sb = new StringBuffer(20);
try {
// String imgPath = StringBufferUtil.append(sb, ManagerConf.getMangerConf().getProductSave(),"/",proNo,"/",fileName).toString();
sb.append("/base/stt/img/");
FileUtil.createDirNotExists(sb.toString());
String imgPath = sb.toString() + fileName;
if(!FileUtil.fileExists(imgPath)){
return;
}
ServletOutputStream os = response.getOutputStream();
fis = new FileInputStream(imgPath);
byte[] bs = new byte[fis.available()];
fis.read(bs);
os.write(bs);
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
if(fis != null)fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
最后,测试多图同时上传一下吧:
需要注意的地方,返回的json数据格式如下:
{"errno":0,"data":["/stt/file/image/2017062922410001580284.jpg/","/stt/file/image/2017062922410001546426.jpg/","/stt/file/image/2017062922410001522021.gif/"]}
errno
为0是成功上传完到后端后给前台的提示,都需要返回给前端页面。
这个弄清楚上传的流程就好了,代码这块自己发挥下就行。
我的博客文章地址:http://www.hanyz.cn/2017/06/29/%E4%BB%8B%E7%BB%8D%E4%B8%A4%E7%A7%8D%E5%AF%8C%E6%96%87%E6%9C%AC%E7%BC%96%E8%BE%91%E5%99%A8/