承前一篇使用Servlet上傳檔案,此篇改寫Servlet使用JSP來上傳圖片、Flash或檔案,取得設定檔部份由web.xml設定改成讀取外部properties設定檔,在前端javascript部份只需要修改CKConfig裡的上傳使用的三個參數就可以了。
filebrowserUploadUrl : 'CKEditorUpload.jsp?Type=File', filebrowserImageUploadUrl : 'CKEditorUpload.jsp?Type=Image', filebrowserFlashUploadUrl : 'CKEditorUpload.jsp?Type=Flash',
原始碼設定部份:
init.properties
baseDir=/UserFiles/ enabled=true AllowedExtensionsFile= DeniedExtensionsFile=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 AllowedExtensionsImage=jpg|gif|jpeg|png|bmp DeniedExtensionsImage= AllowedExtensionsFlashs=wf|fla DeniedExtensionsFlash=
CKEditorUpload.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><%!private org.apache.log4j.Logger logger = org.apache.log4j.Logger .getLogger(this.getClass()); private static String baseDir;// CKEditor上傳檔案存放的目錄 private static boolean debug = false;// 是否debug模式 private static boolean enabled = false; private static java.util.Hashtable<String, java.util.ArrayList<String>> allowedExtensions;//可上傳的副檔名 private static java.util.Hashtable<String, java.util.ArrayList<String>> deniedExtensions;//不可上傳的副檔名 private static java.text.SimpleDateFormat dirFormatter;// 目錄格式yyyMM private static java.text.SimpleDateFormat fileFormatter;// 文件格式yyyyMMddHHmmssSSS private static java.util.Properties prof = null; //初始化 public void init() throws ServletException { if (prof == null) { try { prof = yku.yslifes.PropertiesWithStream.loadInit(); } catch (java.io.IOException e) { throw new ServletException("無法取得init.properties資料"); } } //debug mode? logger.debug("---- SimpleUploaderServlet initialization started ----"); // 目錄及文件的命名格式 dirFormatter = new java.text.SimpleDateFormat("yyyyMM"); fileFormatter = new java.text.SimpleDateFormat("yyyyMMddHHmmssSSS"); // 存放檔案的根目錄 baseDir = prof.getProperty("baseDir"); // 是否可上傳檔案 enabled = (new Boolean(prof.getProperty("enabled"))).booleanValue(); if (baseDir == null) baseDir = "/UserFiles/"; String realBaseDir = getServletContext().getRealPath(baseDir); java.io.File baseFile = new java.io.File(realBaseDir); if (!baseFile.exists()) { baseFile.mkdirs(); } // 黑名單及白名單,可上傳之副檔名 allowedExtensions = new java.util.Hashtable<String, java.util.ArrayList<String>>( 3); deniedExtensions = new java.util.Hashtable<String, java.util.ArrayList<String>>( 3); // allowedExtensions.put("File", stringToArrayList(prof.getProperty("AllowedExtensionsFile"))); deniedExtensions.put("File", stringToArrayList(prof.getProperty("DeniedExtensionsFile"))); allowedExtensions.put("Image", stringToArrayList(prof.getProperty("AllowedExtensionsImage"))); deniedExtensions.put("Image", stringToArrayList(prof.getProperty("DeniedExtensionsImage"))); allowedExtensions.put("Flash", stringToArrayList(prof.getProperty("AllowedExtensionsFlash"))); deniedExtensions.put("Flash", stringToArrayList(prof.getProperty("DeniedExtensionsFlash"))); logger.debug("---- SimpleUploaderServlet initialization completed ----\r\n"); } /** * 取得檔案檔名 */ 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 java.util.ArrayList<String> stringToArrayList(String str) { logger.info(str); java.util.ArrayList<String> tmp = new java.util.ArrayList<String>(); if (str != null) { String[] strArr = str.split("\\|"); if (str.length() > 0) { for (int i = 0; i < strArr.length; ++i) { logger.debug(i + " - " + strArr[i]); tmp.add(strArr[i].toLowerCase()); } } } return tmp; } /** * 判斷是否為可上傳檔案 */ private boolean extIsAllowed(String fileType, String ext) { ext = ext.toLowerCase(); java.util.ArrayList<String> allowList = allowedExtensions.get(fileType); java.util.ArrayList<String> denyList = 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; }%> <% response.setContentType("text/html; charset=UTF-8"); response.setHeader("Cache-Control", "no-cache"); %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>File Upload</title> </head> <body> <% logger.debug("--- BEGIN DOPOST ---"); //java.io.PrintWriter out = response.getWriter(); // File/Image/Flash String typeStr = request.getParameter("Type"); if (typeStr == null) { typeStr = "File"; } logger.info(typeStr); // 取得目前時間 java.util.Date dNow = new java.util.Date(); // 要上傳的目錄 String currentPath = baseDir + typeStr + "/" + dirFormatter.format(dNow); // Web的實際位置 String currentDirPath = getServletContext() .getRealPath(currentPath); // 判斷檔案是否存在,不存在時則建立 java.io.File dirTest = new java.io.File(currentDirPath); if (!dirTest.exists()) { dirTest.mkdirs(); } // 檔案上傳後的目錄位置http://xxx.xxx.xx/123/ currentPath = request.getContextPath() + currentPath; logger.info(currentDirPath); String newName = ""; String fileUrl = ""; String ErrorMsg = ""; if (enabled) { // 使用Apache Common的fileupload上傳 org.apache.commons.fileupload.FileItemFactory factory = new org.apache.commons.fileupload.disk.DiskFileItemFactory(); org.apache.commons.fileupload.servlet.ServletFileUpload upload = new org.apache.commons.fileupload.servlet.ServletFileUpload( factory); try { java.util.List items = upload.parseRequest(request); //存放上傳的欄位名稱 java.util.Map fields = new java.util.HashMap(); java.util.Iterator<org.apache.commons.fileupload.FileItem> iter = items .iterator(); while (iter.hasNext()) { org.apache.commons.fileupload.FileItem item = iter .next(); if (item.isFormField()) fields.put(item.getFieldName(), item.getString()); else fields.put(item.getFieldName(), item); } // CKEditor上傳form的upload元件名稱是upload org.apache.commons.fileupload.FileItem uplFile = (org.apache.commons.fileupload.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); java.io.File pathToSave = new java.io.File(currentDirPath, fileName); logger.info("檔案名稱:" + currentDirPath + fileName); fileUrl = currentPath + "/" + fileName; if (extIsAllowed(typeStr, ext)) { int counter = 1; while (pathToSave.exists()) { newName = nameWithoutExt + "_" + counter + "." + ext; fileUrl = currentPath + "/" + newName; pathToSave = new java.io.File(currentDirPath, newName); counter++; } uplFile.write(pathToSave); } else { ErrorMsg = "無效的檔案類型 "; logger.info("無效的檔案類型: " + ext); } } catch (Exception ex) { ErrorMsg = "無法得知的錯誤!"; logger.info(ex); ex.printStackTrace(); } } else { ErrorMsg = "未啟用CKEditor上傳功能!!"; logger.info("未啟用CKEditor上傳功能!!"); } // CKEditorFuncNum是要回傳位置 String callback = request.getParameter("CKEditorFuncNum"); out.println("<script type=\"text/javascript\">"); if (ErrorMsg.equals("")) { out.println("window.parent.CKEDITOR.tools.callFunction(" + callback + ",'" + fileUrl + "',''" + ")"); } else { out.println("alert('" + ErrorMsg + "')"); out.println("history.back();"); } out.println("</script>"); out.flush(); //out.close(); logger.debug("--- END DOPOST ---"); %> </body> </html>
example.js
/*! * Ext JS Library 3.0.0 * Copyright(c) 2006-2009 Ext JS, LLC * [email protected] * http://www.extjs.com/license */ Ext.onReady(function(){ //Ext.QuickTips.init(); // turn on validation errors beside the field globally //Ext.form.Field.prototype.msgTarget = 'side'; var bd = Ext.getBody(); var Form = new Ext.FormPanel({ id: 'Myorm', frame: true, labelAlign: 'top', title: 'CKEditor in ExtJS', bodyStyle:'padding:5px', url:"getHtml.jsp", width: 750, layout: 'form', // Specifies that the items will now be arranged in columns items: [{ //columnWidth: 1, xtype: 'fieldset', labelWidth: 90, title:'CKEditor', defaults: {width: 700, border:false}, // Default config options for child items defaultType: 'textfield', autoHeight: true, bodyStyle: Ext.isIE ? 'padding:0 0 5px 15px;' : 'padding:10px 15px;', border: false, style: { "margin-left": "10px", // when you add custom margin in IE 6... "margin-right": Ext.isIE6 ? (Ext.isStrict ? "-10px" : "-13px") : "0" // you have to adjust for it somewhere else }, items: [{ xtype: 'ckeditor', fieldLabel: 'Editor', name: 'htmlcode', id:'htmlcode', CKConfig: { /* Enter your CKEditor config paramaters here or define a custom CKEditor config file. */ customConfig : 'config.js', // This allows you to define the path to a custom CKEditor config file. //toolbar: 'Full', toolbar:[['Source'/*,'-','Save','NewPage','Preview','-','Templates'*/], ['Cut','Copy','Paste','PasteText','PasteFromWord','-','Print', 'SpellChecker', 'Scayt'], ['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'], /*['Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField'],*/ ['BidiLtr', 'BidiRtl'],['Link','Unlink','Anchor'], '/', ['Bold','Italic','Underline','Strike','-','Subscript','Superscript'], ['NumberedList','BulletedList','-','Outdent','Indent','Blockquote','CreateDiv'], ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'], ['Image','Flash','Table','HorizontalRule','Smiley','SpecialChar','PageBreak'], '/', ['Styles','Format','Font','FontSize'], ['TextColor','BGColor'], ['Maximize', 'ShowBlocks','-'/*,'About'*/] ], skin : 'office2003', filebrowserUploadUrl : 'CKEditorUpload.jsp?Type=File', filebrowserImageUploadUrl : 'CKEditorUpload.jsp?Type=Image', filebrowserFlashUploadUrl : 'CKEditorUpload.jsp?Type=Flash', height : 200//, //width: 700 } }] }],buttons:[{ text:'Save', name:'Save', handler:function() { //alert(123); Form.getForm().submit(); }//.createDelegate(Form.getForm()) }], renderTo: bd }); });
讀取properties的小程式yku.yslifes.PropertiesWithStream
package yku.yslifes; import java.io.IOException; import java.io.InputStream; import java.util.Properties; public class PropertiesWithStream { private org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(this.getClass()); public static Properties loadInit()throws java.io.IOException { PropertiesWithStream propLoader = new PropertiesWithStream(); System.out.println("--- Properties from Class.getResourceAsStream ---"); InputStream in = propLoader.getClass().getResourceAsStream( "/init.properties"); Properties prop = propLoader.getPropertiesFromInputStream(in); propLoader.displayAllProperties(prop); return prop; } private Properties getPropertiesFromInputStream(InputStream in) throws IOException { Properties prop = new Properties(); prop.load(in); return prop; } private void displayAllProperties(Properties prop) { for (Object key : prop.keySet()) logger.info(key + " : " + prop.getProperty(key.toString())); } }
註:form物件記得frame: true才能上傳圖片喔
下一篇會介紹使用php實作上傳介面