一、引言
看项目使用FCKeditor时采用了jsp标签进行配置的,如下:
<FCK:editor instanceName="bean.description">
<jsp:attribute name="value">
<%=bean.getDescription()%>
</jsp:attribute>
<jsp:attribute name="height">
400
</jsp:attribute>
<jsp:attribute name="width">
805px
</jsp:attribute>
</FCK:editor>
标签处理其中就是new了一个FCKeditor,并返回到页面
public int doStartTag() throws JspException {
try {
fckEditor = new FCKeditor((HttpServletRequest) pageContext
.getRequest(), instanceName);
if (Utils.isNotEmpty(width))
fckEditor.setWidth(width);
if (Utils.isNotEmpty(height))
fckEditor.setHeight(height);
if (Utils.isNotEmpty(toolbarSet))
fckEditor.setToolbarSet(toolbarSet);
if (Utils.isNotEmpty(value))
fckEditor.setValue(value);
if (Utils.isNotEmpty(basePath))
fckEditor.setBasePath(basePath);
} catch (Exception e) {
throw new JspException(e);
}
return EVAL_BODY_INCLUDE;
}
public int doEndTag() throws JspException {
JspWriter out = pageContext.getOut();
try {
//传到网页
out.println(fckEditor);
} catch (IOException e) {
throw new JspException(
"Tag response could not be written to the user!", e);
}
return EVAL_PAGE;
}
其中就用到了out.println()
二、out.println()
out:JspWriter对象表示服务器端向客户浏览器输出的流,但是这个流会在response中进行缓冲,并不是直接向客户输出。在一个servlet中,所有的流写入语句执行完后,servlet会把这些语句的缓存内容打包成http响应返回给浏览器。有一个现象不知道你注意了没?有一个方法:setHeader(还是setHead我忘了),他是设置http响应头的。不管你多晚才执行了setHeader,setHeader之前有多少个out.print,最终返回给浏览器的数据中setHeader的内容肯定在out.print内容的前面,这可以证明out的内容会被先缓存。所以out的内容会被先缓存在response中,最后再一次性给浏览器。
这里了传入的是FCKeditor对象,看其out.println()源码:
public void println(Object x)
throws IOException
{
print(x);
println();
}
public void print(Object obj)
throws IOException
{
//调用对象的toString()方法
write(String.valueOf(obj));
}
这个就牵扯到网络I/O了,都是字符串转换成字节流在网络中传输。out.println()也用于ajax中回传数据,列如
public ActionForward performPronum(ActionMapping mapping,
ActionForm form, HttpServletRequest request,
HttpServletResponse response) {
try {
HashMap localHashMap1 = new HashMap();
......
response.setContentType("text/json;charset=gb2312");
response.getWriter().println(JsonUtil.toString(localHashMap1));
return null;
} catch (Exception ex) {
}
return null;
}
三,FCKeditor的toString()方法
其中使用的是iframe,嵌入网页的方法,里面还牵扯到配置文件配置的路径问题
public String toString() {
StringBuffer strEditor = new StringBuffer();
strEditor.append("<div>");
String encodedValue = escapeXml(value);
if (Compatibility.isCompatibleBrowser(request)) {
strEditor.append(createInputForVariable(instanceName, instanceName,
encodedValue));
// create config HTML
String configStr = fckConfig.getUrlParams();
if (Utils.isNotEmpty(configStr))
strEditor.append(createInputForVariable(null, instanceName
.concat("___Config"), configStr));
// create IFrame
StringBuffer editorLink = new StringBuffer(request.getContextPath());
editorLink.append(basePath); //从配置文件中获取/resources/default.properties
editorLink.append("/editor/fckeditor.html?InstanceName=")
.append(instanceName);
if (Utils.isNotEmpty(toolbarSet))
editorLink.append("&Toolbar=").append(toolbarSet);
XHtmlTagTool iframeTag = new XHtmlTagTool("iframe",
XHtmlTagTool.SPACE);
iframeTag.addAttribute("id", instanceName.concat("___Frame"));
iframeTag.addAttribute("src", editorLink.toString());
iframeTag.addAttribute("width", width);
iframeTag.addAttribute("height", height);
iframeTag.addAttribute("frameborder", "0");
iframeTag.addAttribute("scrolling", "no");
strEditor.append(iframeTag);
} else {
XHtmlTagTool textareaTag = new XHtmlTagTool("textarea",
encodedValue);
textareaTag.addAttribute("name", instanceName);
textareaTag.addAttribute("rows", "4");
textareaTag.addAttribute("cols", "40");
textareaTag.addAttribute("wrap", "virtual");
textareaTag.addAttribute("style", "width: ".concat(width).concat(
"; height: ").concat(height));
}
strEditor.append("</div>");
return strEditor.toString();
}
四、配置完成后
五,文件上传
fckeditor - (4)文件上传
fckeditor默认不支持文件上传,需要下载web服务器端程序(fckeditor.java),并进行配置
1.在web.xml中加入ConnectorServlet的配置信息
Xml代码
<servlet>
<servlet-name>Connector</servlet-name>
<servlet-class>
net.fckeditor.connector.ConnectorServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Connector</servlet-name>
<url-pattern>
/fckeditor/editor/filemanager/connectors/*
</url-pattern>
</servlet-mapping>
2.在classpath路径上创建fckeditor.properties(在src文件夹下创建)
Java代码
connector.userActionImpl=net.fckeditor.requestcycle.impl.UserActionImpl
乱码问题:由于fckeditor未考虑中文乱码问题,所以需要对ConnectorServlet做修改
解决fckeditor创建文件夹中文乱码问题
在ConnectorServlet的doGet方法中找到String newFolderStr = UtilsFile.sanitizeFolderName(newFolderName);这行代码,在其上添加如下2行代码。
Java代码
//NewFolderName为新创建的文件夹名称,先用iso-8859-1编码将字符串还原成字节数组,在用utf-8重新编码
String newFolderName = request.getParameter("NewFolderName");
newFolderName = new String(newFolderName.getBytes("iso-8859-1"), "utf-8");
String newFolderStr = UtilsFile.sanitizeFolderName(newFolderName);
解决上传文件名为中文文件时出现乱码
fckeditor在java平台采用的是commons-upload组件进行文件上传,只要修改ServletFileUpload的headerEncoding属性为utf-8就能解决上传文件名是中文时所出现的乱码问题。在ConnectorServlet的doPost方法中找到ServletFileUpload upload = new ServletFileUpload(factory);在其后加入下面代码
Java代码
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
//解决上传文件名为中文名时出现乱码
upload.setHeaderEncoding("utf-8");
中文图片不能引用
修改server.xml 端口为8080的Connector,添加属性URIEncoding="UTF-8"
Xml代码
<Connector port="8080" maxHttpHeaderSize="8192"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
connectionTimeout="20000" disableUploadTimeout="true" URIEncoding="UTF-8" />
解决上传文件名重名问题
上传文件名用uuid随机生成的32位字符串代替,防止文件名重复
Java代码
String filename = FilenameUtils.getName(rawName);
String baseName = FilenameUtils.removeExtension(filename);
String extension = FilenameUtils.getExtension(filename);
//上传文件名用uuid随机生成的32位字符串代替,防止文件名重复
filename=UUID.randomUUID().toString().replace("-", "")+"."+extension;
控制允许上传文件的文件类型
fckeditor把上传的文件分为四种:file,Image,Flash,Media
fckeditor会对上传文件的类型进行两次验证(前台javascript验证和后台java验证)所以需要对myconfig.js和fckeditor.propertise进行配置
例如:限制上传图片格式为gif和png
在myconfig.js增加下面配置(可参看fckconfig.js的具体配置选项)
Js代码
FCKConfig.ImageUploadAllowedExtensions = ".(gif|png)$" ;
在fckeditor.propertise进行配置(可参看)
Java代码
connector.resourceType.image.extensions.allowed=gif|png
控制允许上传文件的文件大小
1.在服务端的servlet中,在保存文件之前先判断一下文件大小,如果超出限制,就传递一个自定义的错误码,并且不再保存文件,在ConnectorServlet的doPost方法中找到if (!ExtensionsHandler.isAllowed(resourceType, extension))
在后面添加else if语句块
Java代码
//如果文件的扩展名不允许上传
if (!ExtensionsHandler.isAllowed(resourceType, extension))
ur = new UploadResponse(UploadResponse.SC_INVALID_EXTENSION);
//如果文件大小超出限制10k
else if(uplFile.getSize()>10*1024){
//传递一个自定义的错误码
ur = new UploadResponse(204);
}
//如果不存在以上错误,则保存文件
else {
...
}
2.修改对应的页面中的回调函数,增加对这个自定义的错误码的处理
找到fckeditor/editor/filemanager/browser/default/frmupload.html和fckeditor/editor/dialog/fck_image/fck_image.js中的OnUploadCompleted方法,
在switch 语句块中添加如下代码
Js代码
case 204 :
alert( '文件太大' ) ;
break ;