編輯器

CKEditor 3開啓文件上傳功能(Servlet實現) 轉載自 http://sarin.javaeye.com/blog/599499
本文在http://sarin.javaeye.com/blog/599056介紹的基礎之上進行進一步的研究。
在CKEditor中把上傳配置給打開,很簡單,腳本段改爲如下設置:
Js代碼
<script type="text/javascript">
CKEDITOR.replace('content',{filebrowserUploadUrl : '/ckeditor/ckeditor/uploader?Type=File',
filebrowserImageUploadUrl : '/ckeditor/ckeditor/uploader?Type=Image',
filebrowserFlashUploadUrl : '/ckeditor/ckeditor/uploader?Type=Flash'
});
</script>

這裏參數我們可以自己設置,加個Type爲了區分文件類型,因爲都使用同一個Servlet處理。事情沒有這麼簡單,CKEditor畢竟是個複雜的組件,我們這麼配置,看看它給我們還原成什麼了吧,在FireFox中使用FireBug查看,看到了這些:

看到了吧,在Type後面它爲我們又掛接了幾個參數,其中我們需要的是CKEditorFuncNum和file域的name值upload,CKEditorFuncNum這個參數是用來回調頁面的,就是上傳成功後,頁面自動切換到“圖像”選項卡。upload參數是servlet獲取上傳文件用的參數名。其餘參數就根據需要進行了。
這些參數的名稱都是查看源碼獲得的,不能想當然。有了這些東西后面就好辦了,就是文件上傳了麼。很簡單了。這裏我們使用apache commons組件中的fileupload和io。
先看web.xml,我們做些設置。
Xml代碼
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

<servlet>
<servlet-name>SimpleUploader</servlet-name>
<servlet-class>ckeditor.CKEditorUploadServlet</servlet-class>
<init-param>
<param-name>baseDir</param-name>
<param-value>/UserFiles/</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>enabled</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>AllowedExtensionsFile</param-name>
<param-value></param-value>
</init-param>
<init-param>
<param-name>DeniedExtensionsFile</param-name>
<param-value>
html|htm|php|php2|php3|php4|php5|phtml|pwml|inc|asp|aspx|ascx|jsp|cfm|cfc|pl|bat|exe|com|dll|vbs|js|reg|cgi|htaccess|asis|ftl
</param-value>
</init-param>
<init-param>
<param-name>AllowedExtensionsImage</param-name>
<param-value>jpg|gif|jpeg|png|bmp</param-value>
</init-param>
<init-param>
<param-name>DeniedExtensionsImage</param-name>
<param-value></param-value>
</init-param>
<init-param>
<param-name>AllowedExtensionsFlash</param-name>
<param-value>swf|fla</param-value>
</init-param>
<init-param>
<param-name>DeniedExtensionsFlash</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>SimpleUploader</servlet-name>
<url-pattern>/ckeditor/uploader</url-pattern>
</servlet-mapping>

<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>

主要是Servlet的初始化參數,規定了文件上傳的擴展名規則,就是允許上傳的類型和阻止上傳的類型。分爲File,Image和FLASH三種,這個上傳參數的設置是對應的。Debug是設置servlet知否進行debug,默認是關閉的。enabled是設置該servlet是否有效,如果禁止上傳,就打成false。還有一個baseDir是設定CKEditor上傳文件的存放位置。
下面就是實現類了,比較長,但是有詳細的註釋:
Java代碼
package ckeditor;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
public class CKEditorUploadServlet extends HttpServlet {
private static String baseDir;// CKEditor的根目錄
private static boolean debug = false;// 是否debug模式
private static boolean enabled = false;// 是否開啓CKEditor上傳
private static Hashtable allowedExtensions;// 允許的上傳文件擴展名
private static Hashtable deniedExtensions;// 阻止的上傳文件擴展名
private static SimpleDateFormat dirFormatter;// 目錄命名格式:yyyyMM
private static SimpleDateFormat fileFormatter;// 文件命名格式:yyyyMMddHHmmssSSS
/**
* Servlet初始化方法
*/
public void init() throws ServletException {
// 從web.xml中讀取debug模式
debug = (new Boolean(getInitParameter("debug"))).booleanValue();
if (debug)
System.out
.println("\r\n---- SimpleUploaderServlet initialization started ----");
// 格式化目錄和文件命名方式
dirFormatter = new SimpleDateFormat("yyyyMM");
fileFormatter = new SimpleDateFormat("yyyyMMddHHmmssSSS");
// 從web.xml中獲取根目錄名稱
baseDir = getInitParameter("baseDir");
// 從web.xml中獲取是否可以進行文件上傳
enabled = (new Boolean(getInitParameter("enabled"))).booleanValue();
if (baseDir == null)
baseDir = "/UserFiles/";
String realBaseDir = getServletContext().getRealPath(baseDir);
File baseFile = new File(realBaseDir);
if (!baseFile.exists()) {
baseFile.mkdirs();
}
// 實例化允許的擴展名和阻止的擴展名
allowedExtensions = new Hashtable(3);
deniedExtensions = new Hashtable(3);
// 從web.xml中讀取配置信息
allowedExtensions.put("File",
stringToArrayList(getInitParameter("AllowedExtensionsFile")));
deniedExtensions.put("File",
stringToArrayList(getInitParameter("DeniedExtensionsFile")));
allowedExtensions.put("Image",
stringToArrayList(getInitParameter("AllowedExtensionsImage")));
deniedExtensions.put("Image", stringToArrayList(getInitParameter("DeniedExtensionsImage")));
allowedExtensions.put("Flash", stringToArrayList(getInitParameter("AllowedExtensionsFlash")));
deniedExtensions.put("Flash", stringToArrayList(getInitParameter("DeniedExtensionsFlash")));
if (debug)
System.out
.println("---- SimpleUploaderServlet initialization completed ----\r\n");
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
if (debug)
System.out.println("--- BEGIN DOPOST ---");
response.setContentType("text/html; charset=UTF-8");
response.setHeader("Cache-Control", "no-cache");
PrintWriter out = response.getWriter();
// 從請求參數中獲取上傳文件的類型:File/Image/Flash
String typeStr = request.getParameter("Type");
if (typeStr == null) {
typeStr = "File";
}
if (debug)
System.out.println(typeStr);
// 實例化dNow對象,獲取當前時間
Date dNow = new Date();
// 設定上傳文件路徑
String currentPath = baseDir + typeStr + "/"
+ dirFormatter.format(dNow);
// 獲得web應用的上傳路徑
String currentDirPath = getServletContext().getRealPath(currentPath);
// 判斷文件夾是否存在,不存在則創建
File dirTest = new File(currentDirPath);
if (!dirTest.exists()) {
dirTest.mkdirs();
}
// 將路徑前加上web應用名
currentPath = request.getContextPath() + currentPath;
if (debug)
System.out.println(currentDirPath);
// 文件名和文件真實路徑
String newName = "";
String fileUrl = "";
if (enabled) {
// 使用Apache Common組件中的fileupload進行文件上傳
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
try {
List items = upload.parseRequest(request);
Map fields = new HashMap();
Iterator iter = items.iterator();
while (iter.hasNext()) {
FileItem item = (FileItem) iter.next();
if (item.isFormField())
fields.put(item.getFieldName(), item.getString());
else
fields.put(item.getFieldName(), item);
}
// CEKditor中file域的name值是upload
FileItem uplFile = (FileItem) fields.get("upload");
// 獲取文件名並做處理
String fileNameLong = uplFile.getName();
fileNameLong = fileNameLong.replace('\\', '/');
String[] pathParts = fileNameLong.split("/");
String fileName = pathParts[pathParts.length - 1];
// 獲取文件擴展名
String ext = getExtension(fileName);
// 設置上傳文件名
fileName = fileFormatter.format(dNow) + "." + ext;
// 獲取文件名(無擴展名)
String nameWithoutExt = getNameWithoutExtension(fileName);
File pathToSave = new File(currentDirPath, fileName);
fileUrl = currentPath + "/" + fileName;
if (extIsAllowed(typeStr, ext)) {
int counter = 1;
while (pathToSave.exists()) {
newName = nameWithoutExt + "_" + counter + "." + ext;
fileUrl = currentPath + "/" + newName;
pathToSave = new File(currentDirPath, newName);
counter++;
}
uplFile.write(pathToSave);
} else {
if (debug)
System.out.println("無效的文件類型: " + ext);
}
} catch (Exception ex) {
if (debug)
ex.printStackTrace();
}
} else {
if (debug)
System.out.println("未開啓CKEditor上傳功能");
}
// CKEditorFuncNum是回調時顯示的位置,這個參數必須有
String callback = request.getParameter("CKEditorFuncNum");
out.println("<script type=\"text/javascript\">");
out.println("window.parent.CKEDITOR.tools.callFunction(" + callback
+ ",'" + fileUrl + "',''" + ")");
out.println("</script>");
out.flush();
out.close();
if (debug)
System.out.println("--- END DOPOST ---");
}
/**
* 獲取文件名的方法
*/
private static String getNameWithoutExtension(String fileName) {
return fileName.substring(0, fileName.lastIndexOf("."));
}
/**
* 獲取擴展名的方法
*/
private String getExtension(String fileName) {
return fileName.substring(fileName.lastIndexOf(".") + 1);
}
/**
* 字符串像ArrayList轉化的方法
*/
private ArrayList stringToArrayList(String str) {
if (debug)
System.out.println(str);
String[] strArr = str.split("\\|");
ArrayList tmp = new ArrayList();
if (str.length() > 0) {
for (int i = 0; i < strArr.length; ++i) {
if (debug)
System.out.println(i + " - " + strArr[i]);
tmp.add(strArr[i].toLowerCase());
}
}
return tmp;
}
/**
* 判斷擴展名是否允許的方法
*/
private boolean extIsAllowed(String fileType, String ext) {
ext = ext.toLowerCase();
ArrayList allowList = (ArrayList) allowedExtensions.get(fileType);
ArrayList denyList = (ArrayList) deniedExtensions.get(fileType);
if (allowList.size() == 0) {
if (denyList.contains(ext)) {
return false;
} else {
return true;
}
}
if (denyList.size() == 0) {
if (allowList.contains(ext)) {
return true;
} else {
return false;
}
}
return false;
}
}

只要在頁面中的script中設置了上傳屬性,我們打開圖片時就能看到上傳選項卡了,選擇圖片後,點擊上傳到服務器,上傳成功就會自動跳到圖像選項卡,可以看到源文件已經存在服務器的目標目錄中了,此時,我們就可以在編輯器中編輯上傳的圖片了,非常方便。

下面我們進行圖片上傳測試,可以看到如下效果。

提交後可以看到,數據獲得效果,是完全一致的,這樣使用CKEditor上傳文件就已經成功了。

我們查看源文件,得到如下結果。
Html代碼
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Display Content</title>
</head>
<body>
<center>
<table width="600" border="0" bordercolor="000000"
style="table-layout: fixed;">
<tbody>
<tr>
<td width="100" bordercolor="ffffff">主題:</td>
<td width="500" bordercolor="ffffff">圖片上傳測試</td>
</tr>
<tr>
<td valign="top" bordercolor="ffffff">內容:</td>
<td valign="top" bordercolor="ffffff">
<p style="text-align: center;"><span style="color: #f00;"><strong><span
style="font-family: courier new, courier, monospace;"><span
style="font-size: 48px;">圖片上傳測試</span></span></strong></span></p>
<p style="text-align: center;"><img alt=""
src="/ckeditor/UserFiles/Image/201002/20100217232748000.gif"
style="width: 133px; height: 41px;"></p>
<p style="text-align: center;"><span
style="font-family: courier new, courier, monospace;"><br>
</span></p>
</td>
</tr>
</tbody>
</table>
</center>
</body>
</html>

在服務器目錄中,上傳的文件已經存在其中了。

歡迎交流,希望對使用者有用。
發佈了34 篇原創文章 · 獲贊 2 · 訪問量 1605
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章