[ExtJS]使用Servlet上傳檔案圖片-WYSIWYG所視即所得網頁編輯器外掛 with CKEditor

在上一篇[ExtJS]WYSIWYG所視即所得網頁編輯器外掛 with CKEditor有提到如何在ExtJS裡使用WYSIWYG所視即所得的網頁編輯器,不過並沒有上傳檔案或圖片的功能,要開啟上傳的功能只需要在CKConfig增加三個參數設定指定要做上傳動作的url就可以啟動了,在這篇並附上Servlet實作傳檔的功能。

        filebrowserUploadUrl : 'ckeditor/uploader?Type=File',//檔案上傳的url
        filebrowserImageUploadUrl : 'ckeditor/uploader?Type=Image',//圖檔上傳的url
        filebrowserFlashUploadUrl : 'ckeditor/uploader?Type=Flash',//flash上傳的url

加上以上參數後會在以下三個動作加上一個上傳的tab,可上傳檔案至Server端存放

檔案上傳(插入超連結)

檔案上傳(插入超連結)

上傳Flash

上傳Flash

上傳Image圖檔

上傳Image圖檔picture

上傳完成後會呼叫javascript function來設定資訊,ex影像資訊

ExtJS CKEditor上傳Picture後存放的路徑及檔案

ExtJS CKEditor預覽上傳結果

程式碼部份跟上一篇是相同的,補上修改的部份及Servlet上傳範例

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 : 'ckeditor/uploader?Type=File',   
                    filebrowserImageUploadUrl : 'ckeditor/uploader?Type=Image',   
                    filebrowserFlashUploadUrl : 'ckeditor/uploader?Type=Flash',
                    height : 200//,
                    //width: 700
                }
            }]
        }],buttons:[{
                         text:'Save',
                         name:'Save',
                         handler:function()
                         {
                             //alert(123);
                             Form.getForm().submit();
                         }//.createDelegate(Form.getForm())
                     }],
        renderTo: bd
    });
});

ckeditor.CKEditorUploadServlet.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;
    private static Hashtable allowedExtensions;//可上傳的副檔名
    private static Hashtable deniedExtensions;//不可上傳的副檔名
    private static SimpleDateFormat dirFormatter;// 目錄格式yyyMM
    private static SimpleDateFormat fileFormatter;// 文件格式yyyyMMddHHmmssSSS
    /**
     * Servlet初始化方法
     */
    public void init() throws ServletException {
        //web.xml如果設為debug mode
        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);
        // 取得目前時間
        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();
        }
        // 檔案上傳後的目錄位置http://xxx.xxx.xx/123/
        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);
                }
                // CKEditor上傳form的upload元件名稱是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;
    }
}

web.xml Servlet設定部份

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
    <display-name>ExtCK</display-name>
  
    <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>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
    </welcome-file-list>
</web-app>

註:此範例下載後在tomcat 6及jdk1.6下可使用,如需在其它環境上請再自行編譯過
註:form物件記得frame: true才能上傳圖片喔

原始碼下載

下一篇會介紹改寫Servlet後的jsp上傳檔案方式

參考網站:

http://sarin.javaeye.com/blog/599499

One thought to “[ExtJS]使用Servlet上傳檔案圖片-WYSIWYG所視即所得網頁編輯器外掛 with CKEditor”

發表迴響