首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

CKEditor 圖片上傳至服務器完整實戰:Servlet 實現與常見坑點排查

     編輯:Java 綜合教學

業務場景

富文本編輯器 CKEditor 需要將用戶上傳的圖片存儲到服務器,並返回圖片 URL 供編輯器回顯。本文提供一個基於 Servlet 3.0 + Apache Commons FileUpload 的完整實現,並梳理關鍵配置細節。

核心組件

  1. ImageUploadServlet:處理 multipart/form-data 請求,保存文件,回調 CKEditor。
  2. DateUtil:生成時間戳文件名,避免衝突。
  3. PropertiesUtil:讀取存儲路徑配置。

關鍵代碼實現

1. 圖片上傳 Servlet

@WebServlet("/upload/image")
public class ImageUploadServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("text/html;charset=UTF-8");
        request.setCharacterEncoding("UTF-8");

        PrintWriter out = response.getWriter();
        DiskFileItemFactory factory = new DiskFileItemFactory();
        ServletFileUpload upload = new ServletFileUpload(factory);

        try {
            List<FileItem> items = upload.parseRequest(request);
            for (FileItem item : items) {
                if (item.isFormField()) continue; // 僅處理文件域

                // 生成唯一文件名:yyyyMMddHHmmss + 原始擴展名
                String timestamp = DateUtil.getCurrentDateStr();
                String ext = item.getName().substring(item.getName().lastIndexOf("."));
                String fileName = timestamp + ext;

                // 獲取部署絕對路徑:/webapps/ROOT/userImage/
                String basePath = getServletContext().getRealPath("/userImage");
                File dir = new File(basePath);
                if (!dir.exists()) dir.mkdirs();

                File savedFile = new File(dir, fileName);
                item.write(savedFile);

                // CKEditor 要求的回調腳本
                String callback = request.getParameter("CKEditorFuncNum");
                String fileUrl = request.getContextPath() + "/userImage/" + fileName;
                out.println("<script type=\"text/javascript\">");
                out.println("window.parent.CKEDITOR.tools.callFunction(" + callback + ",'" + fileUrl + "','');");
                out.println("</script>");
                out.flush();
            }
        } catch (Exception e) {
            log("圖片上傳失敗", e);
            out.println("<script>alert('上傳失敗:" + e.getMessage() + "');</script>");
        }
    }
}

2. 工具類

// DateUtil.java
public class DateUtil {
    public static String getCurrentDateStr() {
        return new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
    }
}

// PropertiesUtil.java(可選,若路徑固定可直接寫死)
public class PropertiesUtil {
    public static String getValue(String key) {
        try (InputStream in = PropertiesUtil.class.getResourceAsStream("/text.properties")) {
            Properties p = new Properties();
            p.load(in);
            return p.getProperty(key);
        } catch (IOException e) { throw new RuntimeException(e); }
    }
}

3. 配置文件 text.properties

userImage=userImage/
pageSize=5
imagePath=webapps/ROOT/userImage/

前端 CKEditor 配置

CKEDITOR.replace('editor', {
    filebrowserUploadUrl: '/upload/image',  // 對應 Servlet 路徑
    filebrowserUploadMethod: 'form'
});

常見坑點與排查

現象原因解決
上傳後編輯器無圖片回調 URL 錯誤(用了絕對磁碟路徑而非 Web 可訪問路徑)返回 request.getContextPath() + "/userImage/xxx.jpg"
中文文件名亂碼未設定編碼或 Tomcat connector 無 URIEncodingrequest.setCharacterEncoding("UTF-8"); server.xml 添加 URIEncoding="UTF-8"
大文件上傳失敗Commons FileUpload 預設大小限制upload.setFileSizeMax(10 * 1024 * 1024); // 10MB
權限拒絕目錄寫入權限不足確保部署用戶對 webapps/ROOT/userImage 有寫權限

進階優化建議

  • 引入圖片壓縮/縮略圖生成(Thumbnailator)。
  • 對接對象存儲(OSS/S3),返回 CDN URL,實現靜態資源分離。
  • 增加文件類型白名單校驗(item.getContentType())。
  • Spring Boot 環境下可直接使用 MultipartFile 簡化代碼。

掌握上述核心流程與細節,即可快速落地 CKEditor 圖片上傳功能,並避開 90% 的常見問題。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved