Hướng Dẫn Tích Hợp Ckfinder Vào Ckeditor Trong Spring Boot Java
Có thể bạn quan tâm
Link Source: Hướng dẫn tích hợp Ckfinder vào Ckeditor trong Spring Boot JavaThể loại: Java, Lập trìnhTags: Học hành, Lập trình, Spring Framework
Cách tích hợp Ckfinder vào Ckeditor trong project Spring Boot JavaTrong bài viết này mình sẽ hướng dẫn tích hợp Ckfinder và Ckeditor trong project Spring Boot Java. Mình sẽ dùng Ckfinder 2 do Ckfinder 3 chỉ hỗ trợ cho PHP và ASP.NET mà không hỗ trợ cho Java.

Đối với với những web developer việc ứng dụng các WYSIWYG editor vào việc quản trị nội dung cho website dường như là điều bắt buộc. Người dùng có thể dễ dàng cập nhật và định dạng nội dung theo ý muốn một cách dễ dàng như dùng MS Word.
Hiện tại có rất nhiều WYSIWYG editor được các nhà phát triển website sử dụng xem tại đây. Top 10 Jquery HTML5 WYSIWYG Plugins Editor
Giới thiệu Ckeditor
CKEditor (còn gọi là FCKeditor) là một trình soạn thảo mã nguồn mở theo kiểu WYSIWYG (tay làm – mắt thấy) của CKSource.

Cũng giống các trình soạn thảo dành cho web khác, CKEditor sử dụng JavaScript là nền tảng, riêng việc tương tác với server thì CKEditor sử dụng các ngôn ngữ phổ biến sau: ASP, ASP.NET, ColdFusion, Java, JavaScript, Perl, PHP và Python.
CKEditor tương thích với hầu hết các trình duyệt Internet, gồm có: Internet Explorer 6.0+ (Windows), Firefox 2.0+, Safari3.0+, Google Chrome (Windows), Opera 9.50+…
Giới thiệu Ckfinder
CKfinder là 1 trình quản lý file, nó cho phép chúng ta quản lý file, folder trên server bao gồm phân quyền sử dụng, upload file từ client. Hiện tại nếu bạn chỉ sử dụng CKEditor thì chức năng upload ảnh từ client và chèn vào bài viết không sử dụng được
.
Hướng dẫn tích hợp Ckfinder vào Ckeditor trong Spring Boot Java
Vào phần chính nào, hầu hết đa số trên mạng có rất nhiều hướng dẫn tích hợp Ckfinder vào Ckeditor trên PHP, ASP.NET. Thậm chí là Java nhưng hầu như chỉ hướng dẫn tích hợp Ckfinder cho Java web JSP hay Spring Framework với web.xml. Ngay cả document của trang chủ Ckfinder cũng chỉ hướng dẫn theo dạng web.xml. Vì thế mình quyết định viết bài Hướng dẫn tích hợp Ckfinder vào Ckeditor trong Spring Boot Java.
Các công nghệ sử dụng:
- Spring Boot + Thymeleaf
Công cụ yêu cầu:
- Ckfinder 2
- Ckeditor 3
- Eclipse + Plugin spring suite tool
Quá trình làm gồm các bước cụ thể dưới đây! Để chi tiết bạn nên xem video cuối bài !
Tải thư viện Ckfinder và Ckeditor cần thiết
Download Ckfinder java
Download Ckeditor
Cấu trúc thư mục
Tạo Spring Boot project
Eclipse bạn đã cài đặt Plugin spring suite tool. File > New > Spring Starter Project.

Next, sau đó chọn Thymeleaf và Web. Sau đó chọn Finish.
Tích hợp thư viện vào Spring Boot project (pom, static, lib)
Sau khi tải 2 thư viện phía trên về, bạn hãy giải nén ra. Copy 2 folder cần thiết vào thư mục static trong project spring boot:
- ckeditor trong ckeditor_4.8.0_basic
- ckfinder trong ckfinder_java_2.6.2.1\ckfinder\_source\CKFinder for Java\WebApp\src\main\webapp
Copy file file config.xml trong ckfinder_java_2.6.2.1\ckfinder\_source\CKFinder for Java\WebApp\src\main\webapp\WEB-INF và thư mục static.
Đồng thời bạn tạo thư mục uploadmedia trong thư mục static.
Sau đó bạn import CKFinderJava-2.6.2.1.war vào eclipse và lấy 1 số thư viện jar sau:

Sau đó bỏ vào thư mục lib nằm ở ngoài project.
Sau đó copy lib vào spring boot project.
File pom.xml
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.qlam</groupId> <artifactId>ckspringbootqlam</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>ckspringbootqlam</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!--CKFinder start --> <dependency> <groupId>com.ckeditor</groupId> <artifactId>ckeditor-java-core</artifactId> <version>3.5.3</version> </dependency> <dependency> <groupId>com.finder</groupId> <artifactId>fileeditor</artifactId> <version>2.6.2.1</version> <scope>system</scope> <systemPath>$basedir/lib/CKFinderPlugin-FileEditor-2.6.2.1.jar</systemPath> </dependency> <dependency> <groupId>com.finder</groupId> <artifactId>imgresize</artifactId> <version>2.6.2.1</version> <scope>system</scope> <systemPath>$basedir/lib/CKFinderPlugin-ImageResize-2.6.2.1.jar</systemPath> </dependency> <dependency> <groupId>com.finder</groupId> <artifactId>watermark</artifactId> <version>2.6.2.1</version> <scope>system</scope> <systemPath>$basedir/lib/CKFinderPlugin-Watermark-2.6.2.1.jar</systemPath> </dependency> <dependency> <groupId>com.finder</groupId> <artifactId>ckfinder</artifactId> <version>2.6.2.1</version> <scope>system</scope> <systemPath>$basedir/lib/CKFinder-2.6.2.1.jar</systemPath> </dependency> <dependency> <groupId>net.coobird</groupId> <artifactId>thumbnailator</artifactId> <version>0.4.8</version> <scope>system</scope> <systemPath>$basedir/lib/thumbnailator-0.4.8.jar</systemPath> </dependency> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.3</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.5</version> </dependency> <!--CKFinder end --> <dependency> <groupId>javax.activation</groupId> <artifactId>activation</artifactId> <version>1.1.1</version> </dependency> <dependency> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> <version>1.4.7</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build></project>Tạo class Cấu hình project
Tạo package com.qlam.demo.config
Trong này sẽ có 3 file dùng để cấu hình như sau:
File CKFinderConfig.java dùng để đọc file ckfinder.xml
package com.qlam.demo.config;import com.ckfinder.connector.configuration.Configuration;import com.ckfinder.connector.configuration.Events;import com.ckfinder.connector.utils.PathUtils;import org.springframework.core.io.DefaultResourceLoader;import org.springframework.core.io.Resource;import org.w3c.dom.Document;import org.w3c.dom.Node;import org.w3c.dom.NodeList;import javax.servlet.ServletConfig;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.util.Scanner;public class CKFinderConfig extends Configuration public CKFinderConfig(ServletConfig servletConfig) super(servletConfig); @Override public void init() throws Exception DefaultResourceLoader loader = new DefaultResourceLoader(); Resource resource = loader.getResource(this.xmlFilePath); Class<?> clazz = getClass().getSuperclass(); Field field = clazz.getDeclaredField("lastCfgModificationDate"); Method method = clazz.getDeclaredMethod("clearConfiguration"); method.setAccessible(true); method.invoke(this); field.setAccessible(true); field.set(this, System.currentTimeMillis()); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(resource.getInputStream()); doc.normalize(); Node node = doc.getFirstChild(); if (node != null) NodeList nodeList = node.getChildNodes(); //Duyet qua .xml for (int i = 0; i < nodeList.getLength(); ++i) Node childNode = nodeList.item(i); if (childNode.getNodeName().equals("enabled")) this.enabled = Boolean.valueOf(childNode.getTextContent().trim()).booleanValue(); if (childNode.getNodeName().equals("baseDir")) if (servletConf.getInitParameter("baseDir") == null) //baseDir cua application.prop la null this.baseDir = childNode.getTextContent().trim(); //lay the ben ckfinder.xml, khi do phai thiet lap ben ckfinder.xml else //nguoc lai lay ben application.prop this.baseDir = servletConf.getInitParameter("baseDir"); this.baseDir = PathUtils.escape(this.baseDir); this.baseDir = PathUtils.addSlashToEnd(this.baseDir); if (childNode.getNodeName().equals("baseURL")) if (servletConf.getInitParameter("baseURL") == null) this.baseURL = childNode.getTextContent().trim(); else this.baseURL=servletConf.getInitParameter("baseURL")+"/public/image/"; this.baseURL = PathUtils.escape(this.baseURL); this.baseURL = PathUtils.addSlashToEnd(this.baseURL); if (childNode.getNodeName().equals("licenseName")) this.licenseName = childNode.getTextContent().trim(); if (childNode.getNodeName().equals("licenseKey")) this.licenseKey = childNode.getTextContent().trim(); String value; if (childNode.getNodeName().equals("imgWidth")) value = childNode.getTextContent().trim(); value = value.replaceAll("//D", ""); try this.imgWidth = Integer.valueOf(value); catch (NumberFormatException var13) this.imgWidth = null; if (childNode.getNodeName().equals("imgQuality")) value = childNode.getTextContent().trim(); value = value.replaceAll("//D", ""); method = clazz.getDeclaredMethod("adjustQuality", new Class[]String.class); method.setAccessible(true); this.imgQuality = Float.parseFloat(method.invoke(this, value).toString()); if (childNode.getNodeName().equals("imgHeight")) value = childNode.getTextContent().trim(); value = value.replaceAll("//D", ""); try this.imgHeight = Integer.valueOf(value); catch (NumberFormatException var12) this.imgHeight = null; if (childNode.getNodeName().equals("thumbs")) method = clazz.getDeclaredMethod("setThumbs", new Class[]NodeList.class); method.setAccessible(true); method.invoke(this, childNode.getChildNodes()); if (childNode.getNodeName().equals("accessControls")) method = clazz.getDeclaredMethod("setACLs", new Class[]NodeList.class); method.setAccessible(true); method.invoke(this, childNode.getChildNodes()); if (childNode.getNodeName().equals("hideFolders")) method = clazz.getDeclaredMethod("setHiddenFolders", new Class[]NodeList.class); method.setAccessible(true); method.invoke(this, childNode.getChildNodes()); if (childNode.getNodeName().equals("hideFiles")) method = clazz.getDeclaredMethod("setHiddenFiles", new Class[]NodeList.class); method.setAccessible(true); method.invoke(this, childNode.getChildNodes()); if (childNode.getNodeName().equals("checkDoubleExtension")) this.doubleExtensions = Boolean.valueOf(childNode.getTextContent().trim()).booleanValue(); if (childNode.getNodeName().equals("disallowUnsafeCharacters")) this.disallowUnsafeCharacters = Boolean.valueOf(childNode.getTextContent().trim()).booleanValue(); if (childNode.getNodeName().equals("forceASCII")) this.forceASCII = Boolean.valueOf(childNode.getTextContent().trim()).booleanValue(); if (childNode.getNodeName().equals("checkSizeAfterScaling")) this.checkSizeAfterScaling = Boolean.valueOf(childNode.getTextContent().trim()).booleanValue(); Scanner sc; if (childNode.getNodeName().equals("htmlExtensions")) value = childNode.getTextContent(); sc = (new Scanner(value)).useDelimiter(","); while (sc.hasNext()) String val = sc.next(); if (val != null && !val.equals("")) this.htmlExtensions.add(val.trim().toLowerCase()); if (childNode.getNodeName().equals("secureImageUploads")) this.secureImageUploads = Boolean.valueOf(childNode.getTextContent().trim()).booleanValue(); if (childNode.getNodeName().equals("uriEncoding")) this.uriEncoding = childNode.getTextContent().trim(); if (childNode.getNodeName().equals("userRoleSessionVar")) this.userRoleSessionVar = childNode.getTextContent().trim(); if (childNode.getNodeName().equals("defaultResourceTypes")) value = childNode.getTextContent().trim(); sc = (new Scanner(value)).useDelimiter(","); while (sc.hasNext()) this.defaultResourceTypes.add(sc.next()); if (childNode.getNodeName().equals("plugins")) method = clazz.getDeclaredMethod("setPlugins", new Class[]Node.class); method.setAccessible(true); method.invoke(this, childNode); if (childNode.getNodeName().equals("basePathBuilderImpl")) method = clazz.getDeclaredMethod("setBasePathImpl", new Class[]String.class); method.setAccessible(true); method.invoke(this, childNode.getTextContent().trim()); method = clazz.getDeclaredMethod("setTypes", new Class[]Document.class); method.setAccessible(true); method.invoke(this, doc); field = clazz.getDeclaredField("events"); field.setAccessible(true); field.set(this, new Events()); this.registerEventHandlers();File CKFinderServletConfig.java dùng để thiết lập thuộc tính trên file application.properties
package com.qlam.demo.config;import com.ckfinder.connector.ConnectorServlet;import org.springframework.beans.factory.annotation.Value;import org.springframework.boot.web.servlet.ServletRegistrationBean;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class CKFinderServletConfig @Value("$ckeditor.storage.image.path") private String baseDir; @Value("$ckeditor.access.image.url") private String baseURL; @Bean public ServletRegistrationBean connectCKFinder() ServletRegistrationBean registrationBean=new ServletRegistrationBean(new ConnectorServlet(),"/ckfinder/core/connector/java/connector.java"); registrationBean.addInitParameter("XMLConfig","classpath:/static/ckfinder.xml"); registrationBean.addInitParameter("debug","false"); registrationBean.addInitParameter("configuration","com.qlam.demo.config.CKFinderConfig"); //ckfinder.xml registrationBean.addInitParameter("baseDir",baseDir); registrationBean.addInitParameter("baseURL",baseURL); return registrationBean;File WebMvcConfig.java dùng để thiết lập đường dẫn thư viện và file upload theo Spring MVC
package com.qlam.demo.config;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;@Configurationpublic class WebMvcConfig extends WebMvcConfigurerAdapter @Override public void addResourceHandlers(ResourceHandlerRegistry registry) // file:D:\\data\\file\\image\\ registry.addResourceHandler("/public/image/**").addResourceLocations("classpath:/static/uploadmedia/"); registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/"); registry.addResourceHandler("/ckfinder/**").addResourceLocations("classpath:/static/ckfinder/"); super.addResourceHandlers(registry);File application.properties
# ===============================# THYMELEAF# ===============================spring.thymeleaf.cache=false# ===============================# DATASOURCE# ===============================# Set here configurations for the database connection# config dir so that ckeditor and ckfinder loading to media upload, write null so that use ckfinder.xmlckeditor.storage.image.path=src/main/resources/static/uploadmedia/ckeditor.access.image.url=http://localhost:8080Xử lý với Controller class
Tạo package com.qlam.demo.controller
Chúng ta cần 1 class Controller để chạy trang chủ.
File QController.java đơn giản là mình cho nó dùng giao diện file adpost.html để hiện cho trang chủ.
package com.qlam.demo.controller;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.GetMapping;@Controllerpublic class QController @GetMapping("/") public String home() return "adpost";Thiết kế giao diện với thymeleaf engine
Mình tạo giao diện web đơn giản chia làm 2 phần:
- Dùng Ckeditor tích hợp Ckfinder khi upload ảnh
- Chạy Ckfinder khi nhấn một nút
Trong phần src/main/resources/templates tạo file adpost.html
File adpost.html
<html xmlns:th="http://www.thymeleaf.org"><head th:fragment="head"><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" /><meta http-equiv="x-ua-compatible" content="ie=edge" /><title>Ckfinder</title></head><body> <div id="page-content-wrapper"> <h1 id="home" class="text-center font-bold mt-1">Integrate ckfinder into ckeditor in spring boot project</h1> <h2>ShareEverythings.com</h2> <!-- Section: Create Page --> <section class="section mt-5 container-fluid"> <!-- First row --> <div class="row"> <!-- First col --> <div class="col-lg-6"> <h3>A. Integrate ckfinder into ckeditor</h3> <!-- Second card --> <div class="card mb-r"> <textarea name="content" id="content"></textarea> </div> <!-- /.Second card --> </div> <!-- /.First col --> <div class="col-lg-6"> <h3>B. Ckfinder Button</h3> <div class="avatar"> <img id="imgpreview" src="https://yt3.ggpht.com/-f6NCDKG2Ukw/AAAAAAAAAAI/AAAAAAAAAAA/MqMm3rgmqCY/s48-c-k-no-mo-rj-c0xffffff/photo.jpg" class="img-fluid" style="max-width: 300px; max-height: 300px;" /> </div> <div class="file-field"> <p> <strong id="xImagePath">Selected Image URL</strong><br /> <input class="btn btn-primary btn-sm waves-effect waves-light" type="button" value="Browse Image" onclick="BrowseServer( 'Images:/', 'xImagePath' );" /> </p> </div> <p>Note: You should select square image !</p> </div> </div> <!-- /.First row --> </section> <!-- /.Section: Create Page --> </div> <script src="ckeditor/ckeditor.js"></script> <script src="ckfinder/ckfinder.js"></script> <script> CKEDITOR .replace( 'content', filebrowserBrowseUrl : 'ckfinder/ckfinder.html', filebrowserImageBrowseUrl : 'ckfinder/ckfinder.html?type=Images', filebrowserFlashBrowseUrl : 'ckfinder/ckfinder.html?type=Flash', filebrowserUploadUrl : 'ckfinder/core/connector/java/connector.java?command=QuickUpload&type=Files', filebrowserImageUploadUrl : 'ckfinder/core/connector/java/connector.java?command=QuickUpload&type=Images', filebrowserFlashUploadUrl : 'ckfinder/core/connector/java/connector.java?command=QuickUpload&type=Flash' ); /*Avatar start*/ function BrowseServer(startupPath, functionData) // You can use the "CKFinder" class to render CKFinder in a page: var finder = new CKFinder(); // The path for the installation of CKFinder (default = "/ckfinder/"). finder.basePath = '../'; //Startup path in a form: "Type:/path/to/directory/" finder.startupPath = startupPath; // Name of a function which is called when a file is selected in CKFinder. finder.selectActionFunction = SetFileField; // Additional data to be passed to the selectActionFunction in a second argument. // We'll use this feature to pass the Id of a field that will be updated. finder.selectActionData = functionData; // Name of a function which is called when a thumbnail is selected in CKFinder. Preview img // finder.selectThumbnailActionFunction = ShowThumbnails; // Launch CKFinder finder.popup(); // This is a sample function which is called when a file is selected in CKFinder. function SetFileField(fileUrl, data) document.getElementById(data["selectActionData"]).innerHTML = this .getSelectedFile().name; document.getElementById("imgpreview").src = fileUrl; /*Avatar end*/ </script></body></html>Chạy project
Kết quả thành công!




Nhờ các plugin bạn có thể thay đổi kích thước ảnh.


Video chi tiết Hướng dẫn tích hợp Ckfinder vào Ckeditor trong Spring Boot Java
Link Source: Hướng dẫn tích hợp Ckfinder vào Ckeditor trong Spring Boot JavaDownload Full Project Java
https://www.mediafire.com/file/d5u2d8zxo4zbbo8/ckspringbootqlam.7z/file
Từ khóa » Tích Hợp Ckfinder Vào Ckeditor Asp.net
-
Hướng Dẫn Tích Hợp Ckfinder Và CKEditor Vào Website - Vnfree.Net
-
Hướng Dẫn Cài đặt Tích Hợp CKFinder Vào CKEditor
-
Hướng Dẫn Tích Hợp Ckfinder Vào Ckeditor Trong ASP.NET - YouTube
-
Hướng Dẫn Cài đặt Plugin CKEditor Và CKFinder Trong ASP.NET ...
-
Tích Hợp Trình Soạn Thảo CKEditer Và CKFinder
-
Hướng Dẫn Tích Hợp Ckfinder 3.4.2 Và Ckeditor - GÓC LẬP TRÌNH.NET
-
CKFinder 3 ASP.NET Connector: Integration - CKEditor
-
Upload Hình ảnh Trong Ckeditor
-
Hướng Dẫn Tích Hợp Ckfinder Vào Ckeditor Trong ASP.NET دیدئو Dideo
-
Tích Hợp Trình Soạn Thảo CK Editor Vào ứng Dụng ASP.NET MVC
-
Bài 34: Cách Nhúng CKFinder Cho Quản Lý ảnh - TEDU
-
Bài 22: Tích Hợp CK Finder để Quản Lý Thư Viện ảnh Online Vào ứng ...
-
Browser Error Does Not Find The URL To ml - Stack Overflow