本人使用的CKEditor版本是3.6.3。CKEditor配置和部署我就不多说。
CKEditor的编辑器工具栏中有一项“图片域”,该工具可以贴上图片地址来在文本编辑器中加入图片,但是没有图片上传功能。
“预览”中有一坨鸟语,看得很不爽,首先要去掉这些。在ckeditor/config.js中加上一个配置项:
config.image_previewText = ' ';
注意引号里面一定要有个空格,不能是空字符串。
扫除这个障碍,下面来研究图片上传。
step 1:
首先,要开启图片上传功能。
找到ckeditor/plugins/image/dialogs/image.js这个文件,CTRL+F搜索下面一段JS:
id:'Upload',hidden:true
实际上上传功能被隐藏了,把上面的true改成false,再打开编辑器,就能找到上传功能了。
step 2:
上面的只是一个上传页面,也就是一个form表单,要配置点击“上传到服务器上”按钮后请求的Action,可以在ckeditor/config.js中加入一个配置项:
config.filebrowserUploadUrl = "actions/ckeditorUpload";
“actions/ckeditorUpload”是文件上传POST请求的URL,也就是点击这个按钮就会post到actions/ckeditorUpload进行处理,这里指向的是Struts 2的一个Action。当然,也可以用Servlet或者ASP、PHP等来处理请求。
在Struts 2配置文件中,就需要加入对应的配置,来处理actions/ckeditorUpload URL的请求:
<package name="actions" extends="struts-default" namespace="/actions"> <action name="ckeditorUpload" class="com.xxx.CkeditorUpload "> </action> </package>
文件上传的控件相当于<input type="file" name="upload" .../>,其name是”upload”。
知道了name那么就可以在Action中获取这个文件。
private File upload; //文件 private String uploadContentType; //文件类型 private String uploadFileName; //文件名
step 4:
上传过程中的一些错误(例如图片格式不正确、图片太大),可以在界面上进行提示:
这个需要通过HttpServletResponse向客户端写入一段JS来实现:
String callback = ServletActionContext.getRequest().getParameter("CKEditorFuncNum"); if([判断条件]){ out.println("<script type=\"text/javascript\">"); out.println("window.parent.CKEDITOR.tools.callFunction(" + callback + ",'','文件格式不正确(必须为.jpg/.gif/.bmp/.png文件)');"); out.println("</script>"); return null; }
Struts 2上传文件核心代码:
InputStream is = new FileInputStream(upload); String uploadPath = ServletActionContext.getServletContext().getRealPath("/"); String fileName = java.util.UUID.randomUUID().toString(); // 采用UUID的方式命名保证不会重复 fileName += expandedName; File toFile = new File(uploadPath, fileName); OutputStream os = new FileOutputStream(toFile); // 文件复制到指定位置 byte[] buffer = new byte[1024]; int length = 0; while ((length = is.read(buffer)) > 0) { os.write(buffer, 0, length); } is.close(); os.close();
step 6:
图片上传成功,在web app目录下也可以看到图片,但是在点击“确定”后会出现“缺少图像源文件地址”:
这是因为CKEditor并不知道图片放在哪里,所以无法显示在“预览”中。下面out.print一段JS来告诉CKEditor图片的相对路径:
// 返回“图像”选项卡并显示图片 out.println("<script type=\"text/javascript\">"); out.println("window.parent.CKEDITOR.tools.callFunction(" + callback + ",'" + fileName + "','')"); // 相对路径用于显示图片 out.println("</script>"); return null;
最后附上相关代码:
config.js配置:
CKEDITOR.editorConfig = function( config ) { config.image_previewText = ' '; // 去掉图片预览中的鸟语,这里注意里面一定要有个空格 config.filebrowserUploadUrl = "actions/ckeditorUpload"; // 指定上传的目标地址 };
package com.xxg; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import javax.servlet.http.HttpServletResponse; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; public class CkeditorUpload extends ActionSupport { private File upload; private String uploadContentType; private String uploadFileName; public File getUpload() { return upload; } public void setUpload(File upload) { this.upload = upload; } public String getUploadContentType() { return uploadContentType; } public void setUploadContentType(String uploadContentType) { this.uploadContentType = uploadContentType; } public String getUploadFileName() { return uploadFileName; } public void setUploadFileName(String uploadFileName) { this.uploadFileName = uploadFileName; } public String execute() throws Exception { HttpServletResponse response = ServletActionContext.getResponse(); response.setCharacterEncoding("GBK"); PrintWriter out = response.getWriter(); // CKEditor提交的很重要的一个参数 String callback = ServletActionContext.getRequest().getParameter("CKEditorFuncNum"); String expandedName = ""; // 文件扩展名 if (uploadContentType.equals("image/pjpeg") || uploadContentType.equals("image/jpeg")) { // IE6上传jpg图片的headimageContentType是image/pjpeg,而IE9以及火狐上传的jpg图片是image/jpeg expandedName = ".jpg"; } else if (uploadContentType.equals("image/png") || uploadContentType.equals("image/x-png")) { // IE6上传的png图片的headimageContentType是"image/x-png" expandedName = ".png"; } else if (uploadContentType.equals("image/gif")) { expandedName = ".gif"; } else if (uploadContentType.equals("image/bmp")) { expandedName = ".bmp"; } else { out.println("<script type=\"text/javascript\">"); out.println("window.parent.CKEDITOR.tools.callFunction(" + callback + ",'','文件格式不正确(必须为.jpg/.gif/.bmp/.png文件)');"); out.println("</script>"); return null; } if (upload.length() > 600 * 1024) { out.println("<script type=\"text/javascript\">"); out.println("window.parent.CKEDITOR.tools.callFunction(" + callback + ",''," + "'文件大小不得大于600k');"); out.println("</script>"); return null; } InputStream is = new FileInputStream(upload); String uploadPath = ServletActionContext.getServletContext().getRealPath("/"); String fileName = java.util.UUID.randomUUID().toString(); // 采用UUID的方式命名保证不会重复 fileName += expandedName; File toFile = new File(uploadPath, fileName); OutputStream os = new FileOutputStream(toFile); // 文件复制到指定位置 byte[] buffer = new byte[1024]; int length = 0; while ((length = is.read(buffer)) > 0) { os.write(buffer, 0, length); } is.close(); os.close(); // 返回“图像”选项卡并显示图片 out.println("<script type=\"text/javascript\">"); out.println("window.parent.CKEDITOR.tools.callFunction(" + callback + ",'" + fileName + "','')"); // 相对路径用于显示图片 out.println("</script>"); return null; } }
如果需要DEMO的同学请在评论中留下E-mail。