前些日子一个跑业务的朋友帮我接到一个小的项目,其中有好多模块用到了富文本编辑器,在网上找了好多,也看了好多,综合各方面的因素最后选择了kindeditor4.1.8,网上搜索了一下也没有看到一个帖子完完整整的介绍kindeditor4.1.8与struts2整合的过程,到是检索到了零零散散的几分文章作用不是太大~~~好吧,自己动手吧,于是乎我打开了下载的kindeditor4.1.8的组件包,找到了其中的jsp上传文件的那一部分内容看了一边。开始编写Action(个人认为既然都用了struts2框架了就不想写servlet 了)。在这个过程中遇到了很多问题,不过都一一解决了。好了,废话不多说了,开始整合过程:
1.首先下载kindeditor4.1.8(个人比较喜欢新鲜的东西...)
2.打开下载的kindeditor4.1.8的包,先瘦身,把其中的不需要的文件删除掉如下图所示:
3、建立Web项目,并加入struts2的依赖后,把kindeditor4.1.8中的jsp文件夹中的lib里面的json_simple-1.1.jar加入到构建路径中。
4、把kindeditor4.1.8的jsp文件剪切到外面,然后将剩下的全部拷贝到项目的WebRoot下,并建立文件夹attached(上传文件的存储区域)
5、开始创建包、编写action,其中的内容是重写了jsp/upload_json.jsp中的部分内容。代码重写的代码如下:
<注意其中的 import org.maxsoft.tools.FileTools; 是我自己写了一个上传文件的工具类,功能只有两个。
1、计算文件大小;
2、上传文件到指定的目录>
package org.maxsoft.action;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Random;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper;
import org.json.simple.JSONObject;
import org.maxsoft.tools.FileTools;
import com.opensymphony.xwork2.ActionContext;
public class UploadJsonAction {
@SuppressWarnings("unchecked")
public String uploadJson() {
// 最大文件大小
long maxSize = 1024*1024*2;
//获取Struts2中的多媒体请求包装器对象
MultiPartRequestWrapper requestWrapper = (MultiPartRequestWrapper) ActionContext.getContext().get(ServletActionContext.HTTP_REQUEST);
/**
* 通过imgFile获取kindeditor文件上传组件中的文件组以及文件名组
* imgFile是通过分析requestWrapper而拿到的。如下:
* Enumeration attributeNames = requestWrapper.getFileParameterNames();
* System.out.println(attributeNames.nextElement());
*/
//文件名字符串数组
String[] fileNames = requestWrapper.getFileNames("imgFile");
//文件数组
File[] files = requestWrapper.getFiles("imgFile");
// 自定义文件上传工具
FileTools fileTools = new FileTools();
// 获取请求对象
HttpServletRequest request = (HttpServletRequest) ActionContext.getContext().get(ServletActionContext.HTTP_REQUEST);
// 获取响应对象
HttpServletResponse response = (HttpServletResponse) ActionContext.getContext().get(ServletActionContext.HTTP_RESPONSE);
// 文件保存目录路径
String savePath = ServletActionContext.getServletContext().getRealPath("/")+ "attached\\";
// 文件保存目录URL
String saveUrl = ServletActionContext.getServletContext().getContextPath() + "/attached/";
// 定义允许上传的文件扩展名
HashMap<String, String> extMap = new HashMap<String, String>();
extMap.put("image", "gif,jpg,jpeg,png,bmp");
extMap.put("flash", "swf,flv");
extMap.put("media", "swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb");
extMap.put("file", "doc,docx,xls,xlsx,ppt,htm,html,txt,zip,rar,gz,bz2");
response.setContentType("text/html; charset=UTF-8");
if (!ServletFileUpload.isMultipartContent(request)) {
try {
response.getWriter().println(getError("请选择文件。"));
} catch (IOException e) {
System.err.println(e.getMessage());
}
return null;
}
// 检查目录
File uploadDir = new File(savePath);
if (!uploadDir.isDirectory()) {
try {
response.getWriter().println(getError("上传目录不存在。"));
} catch (IOException e) {
System.err.println(e.getMessage());
}
return null;
}
// 检查目录写权限
if (!uploadDir.canWrite()) {
try {
response.getWriter().println(getError("上传目录没有写权限。"));
} catch (IOException e) {
System.err.println(e.getMessage());
}
return null;
}
String dirName = request.getParameter("dir");
if (dirName == null) {
dirName = "image";
}
if (!extMap.containsKey(dirName)) {
try {
response.getWriter().println(getError("目录名不正确。"));
} catch (IOException e) {
System.err.println(e.getMessage());
}
return null;
}
// 创建文件夹
savePath += dirName + "/";
saveUrl += dirName + "/";
File saveDirFile = new File(savePath);
if (!saveDirFile.exists()) {
saveDirFile.mkdirs();
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
String ymd = sdf.format(new Date());
savePath += ymd + "/";
saveUrl += ymd + "/";
File dirFile = new File(savePath);
if (!dirFile.exists()) {
dirFile.mkdirs();
}
for (int i = 0; i < files.length; i++) {
String fileName = fileNames[i];
if(fileTools.getSize(files[i]) > maxSize){
try {
response.getWriter().println(getError("上传文件大小超过限制(<2MB)。"));
} catch (IOException e) {
System.err.println(e.getMessage());
}
return null;
}
// 检查扩展名
String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
if (!Arrays.<String> asList(extMap.get(dirName).split(",")).contains(fileExt)) {
try {
response.getWriter().println(getError("上传文件扩展名是不允许的扩展名。\n只允许"+ extMap.get(dirName) + "格式。"));
} catch (IOException e) {
System.err.println(e.getMessage());
}
return null;
}
SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
String newFileName = df.format(new Date()) + "_"+ new Random().nextInt(1000) + "." + fileExt;
try {
// 生成新的文件的路径
String path = (savePath + "/" + newFileName);
// 判断文件是否上传成功
boolean uploadFile = fileTools.uploadFile(files[i], path);
if (!uploadFile) {
response.getWriter().println(getError("上传文件失败。"));
}
} catch (Exception e) {
try {
response.getWriter().print(getError("上传文件失败。"));
} catch (IOException e1) {
e1.printStackTrace();
}
return null;
}
JSONObject obj = new JSONObject();
obj.put("error", 0);
obj.put("url", saveUrl + newFileName);
try {
response.getWriter().println(obj.toJSONString());
} catch (IOException e) {
System.err.println(e.getMessage());
}
}
return null;
}
//输出信息
@SuppressWarnings("unchecked")
private String getError(String message) {
JSONObject obj = new JSONObject();
obj.put("error", 1);
obj.put("message", message);
return obj.toJSONString();
}
}
以上代码中重写的地方就是在Action中获取页面中kindeditor上传的文件这一块,原来的写法在action中获取不到文件,具体的原因是在action中将request转为了MultiPartRequestWrapper, 因此commons-fileupload这个包中的FileItem就不能使用了。于是就重写了这一块内容。具体思路是:首先从MultiPartRequestWrapper中获取文件名组和文件组,然后自己编写上传文件的工具类实现上传文件。(代码中红色部分为重写)
6、配置struts文件中的action和平常的一样,值得注意的是在action中不用返回结果,因为我们在action输出了json格式的数据,无需返回结果。
7、将kindeditor编辑器放到页面中代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>KindEditor JSP</title>
<link rel="stylesheet" href="kindeditor/themes/default/default.css" />
<link rel="stylesheet" href="kindeditor/plugins/code/prettify.css" />
<script charset="utf-8" src="kindeditor/kindeditor.js"></script>
<script charset="utf-8" src="kindeditor/lang/zh_CN.js"></script>
<script charset="utf-8" src="kindeditor/plugins/code/prettify.js"></script>
<script>
KindEditor.ready(function(K) {
var editor1 = K.create('textarea[name="content1"]', {
cssPath : 'kindeditor/plugins/code/prettify.css',
uploadJson : 'uploadJsonAction.action',
afterCreate : function() {
var self = this;
K.ctrl(document, 13, function() {
self.sync();
document.forms['example'].submit();
});
K.ctrl(self.edit.doc, 13, function() {
self.sync();
document.forms['example'].submit();
});
}
});
prettyPrint();
});
</script>
</head>
<body>
<form name="example" method="post" action="showText.action" enctype="multipart/form-data">
<textarea name="content1" cols="100" rows="8" style="width:700px;height:200px;visibility:hidden;"></textarea>
<br />
<input type="submit" name="button" value="提交内容" /> (提交快捷键: Ctrl + Enter)
</form>
</body>
</html>
8、其中的文件管理由于项目中没有用到就没有去理会。这是我的测试文件结构图:
测试效果图:
图中化红色框的是用到的类,其他类暂时都没有用。
有需要这个测试包的全部内容,请留下邮箱... 或者等过几天我全部整理出来发到网上大家去下载...