KindEditor 是一套开源的 HTML 可视化编辑器,主要用于让用户在网站上获得所见即
所得编辑效果,兼容 IE、Firefox、Chrome、Safari、Opera 等主流浏览器。
KindEditor 使用 JavaScript 编写,可以无缝的于 Java、.NET、PHP、ASP 等程序接合。
KindEditor 非常适合在 CMS、商城、论坛、博客、Wiki、电子邮件等互联网应用上使用,
2006 年 7 月首次发布 2.0 以来,KindEditor 依靠出色的用户体验和领先的技术不断扩大编
辑器市场占有率,目前在国内已经成为最受欢迎的编辑器之一。
官网:http://kindeditor.net
部分代码:
工具类:
FtpUtil:FTPClient 工具类
package com.zxw.commons;import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;/*** ftp上传下载工具类*/
public class FtpUtil {/** * Description: 向FTP服务器上传文件 * @param host FTP服务器hostname * @param port FTP服务器端口 * @param username FTP登录账号 * @param password FTP登录密码 * @param basePath FTP服务器基础目录* @param filePath FTP服务器文件存放路径。例如分日期存放:/2018/01/01。文件的路径为basePath+filePath* @param filename 上传到FTP服务器上的文件名 * @param input 输入流 * @return 成功返回true,否则返回false */
public static boolean uploadFile(String host, int port, String username, String password, String basePath,String filePath, String filename, InputStream input) {boolean result = false;FTPClient ftp = new FTPClient();try {int reply;ftp.connect(host, port);// 连接FTP服务器// 如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器ftp.login(username, password);// 登录reply = ftp.getReplyCode();if (!FTPReply.isPositiveCompletion(reply)) {ftp.disconnect();return result;}//切换到上传目录if (!ftp.changeWorkingDirectory(basePath+filePath)) {//如果目录不存在创建目录String[] dirs = filePath.split("/");String tempPath = basePath;for (String dir : dirs) {if (null == dir || "".equals(dir)) continue;tempPath += "/" + dir;if (!ftp.changeWorkingDirectory(tempPath)) {if (!ftp.makeDirectory(tempPath)) {return result;} else {ftp.changeWorkingDirectory(tempPath);}}}}//设置上传文件的类型为二进制类型ftp.setFileType(FTP.BINARY_FILE_TYPE);//上传文件if (!ftp.storeFile(filename, input)) {return result;}input.close();ftp.logout();result = true;} catch (IOException e) {e.printStackTrace();} finally {if (ftp.isConnected()) {try {ftp.disconnect();} catch (IOException ioe) {}}}return result;}/** * Description: 从FTP服务器下载文件 * @param host FTP服务器hostname * @param port FTP服务器端口 * @param username FTP登录账号 * @param password FTP登录密码 * @param remotePath FTP服务器上的相对路径 * @param fileName 要下载的文件名 * @param localPath 下载后保存到本地的路径 * @return */ public static boolean downloadFile(String host, int port, String username, String password, String remotePath,String fileName, String localPath) {boolean result = false;FTPClient ftp = new FTPClient();try {int reply;ftp.connect(host, port);// 如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器ftp.login(username, password);// 登录reply = ftp.getReplyCode();if (!FTPReply.isPositiveCompletion(reply)) {ftp.disconnect();return result;}ftp.changeWorkingDirectory(remotePath);// 转移到FTP服务器目录FTPFile[] fs = ftp.listFiles();for (FTPFile ff : fs) {if (ff.getName().equals(fileName)) {File localFile = new File(localPath + "/" + ff.getName());OutputStream is = new FileOutputStream(localFile);ftp.retrieveFile(ff.getName(), is);is.close();}}ftp.logout();result = true;} catch (IOException e) {e.printStackTrace();} finally {if (ftp.isConnected()) {try {ftp.disconnect();} catch (IOException ioe) {}}}return result;}
}
IDUtils:生成一切 ID 的策略的工具类。可以使用他生成图片名称
package com.zxw.commons;import java.util.Random;
import java.util.UUID;/*** 各种id生成策略* @version 1.0*/
public class IDUtils {/*** 图片名生成*/public static String genImageName() {//取当前时间的长整形值包含毫秒long millis = System.currentTimeMillis();//long millis = System.nanoTime();//加上三位随机数Random random = new Random();int end3 = random.nextInt(999);//如果不足三位前面补0String str = millis + String.format("%03d", end3);return str;}}
JsonUtils:对象与 json 格式转换的工具类
package com.zxw.commons;import java.util.List;import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;/*** JSON转换工具类*/
public class JsonUtils {// 定义jackson对象private static final ObjectMapper MAPPER = new ObjectMapper();/*** 将对象转换成json字符串。* <p>Title: pojoToJson</p>* <p>Description: </p>* @param data* @return*/public static String objectToJson(Object data) {try {String string = MAPPER.writeValueAsString(data);return string;} catch (JsonProcessingException e) {e.printStackTrace();}return null;}/*** 将json结果集转化为对象* * @param jsonData json数据* @param beanType 对象中的object类型* @return*/public static <T> T jsonToPojo(String jsonData, Class<T> beanType) {try {T t = MAPPER.readValue(jsonData, beanType);return t;} catch (Exception e) {e.printStackTrace();}return null;}/*** 将json数据转换成pojo对象list* <p>Title: jsonToList</p>* <p>Description: </p>* @param jsonData* @param beanType* @return*/public static <T>List<T> jsonToList(String jsonData, Class<T> beanType) {JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType);try {List<T> list = MAPPER.readValue(jsonData, javaType);return list;} catch (Exception e) {e.printStackTrace();}return null;}}
jsp页面
<%--Created by IntelliJ IDEA.User: VivianDate: 2019/9/26Time: 15:52To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Insert title here</title><script type="text/javascript" src="/js/kindeditor/kindeditor.js"></script><script type="text/javascript" src="/js/kindeditor/lang/zh_CN.js"></script><script type="text/javascript" src="/js/jquery-1.7.2.js"></script><script type="text/javascript">$(function(){var obj;KindEditor.ready(function(K) {obj= K.create('#text_id', {uploadJson : '/pic/upload', //指定上传文件的服务器端的程序filePostName:'fileName', //指定上传的文件名dir:"image" //指定上传的文件类型});});//给按钮添加点击事件$("#but").click(function(){//将KindEditor中的数据同步到textarea中obj.sync();//通过ajax方式提交表单 serialize()作用:将表单中的数据序列化为key=value&key=value.....$.post("/content/save",$("#myForm").serialize(),function(data){if(data.status == 200){alert("提交成功");}else{alert("提交失败");}});});});</script>
</head>
<body>
<form id="myForm"><textarea rows="20" cols="20" id="text_id" name="desc"></textarea><input type="button" value="OK" id="but"/>
</form>
</body>
</html>
图片上传service实现类:
package com.zxw.service.impl;import com.zxw.commons.FtpUtil;
import com.zxw.commons.IDUtils;
import com.zxw.service.PicUploadService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@Service
public class PicUploadServiceImpl implements PicUploadService {@Value("${FTP_HOST}")private String FTP_HOST;@Value("${FTP_PORT}")private int FTP_PORT;@Value("${FTP_USERNAME}")private String FTP_USERNAME;@Value("${FTP_PASSWORD}")private String FTP_PASSWORD;@Value("${FTP_BASEPATH}")private String FTP_BASEPATH;@Value("${HTTP_BASE_PATH}")private String HTTP_BASE_PATH;@Overridepublic Map<String, Object> fileUpload(MultipartFile filename) {Map<String, Object> map = new HashMap<>();Date date = new Date();try {//根据上传时间创建文件夹,这样图片不会一直在一个文件夹里,防止图片同名覆盖SimpleDateFormat sdf = new SimpleDateFormat("/yyyy/MM/dd/");String path = sdf.format(date);String newFileName = IDUtils.genImageName()+filename.getOriginalFilename().substring(filename.getOriginalFilename().lastIndexOf("."));boolean flag = FtpUtil.uploadFile(this.FTP_HOST, this.FTP_PORT, this.FTP_USERNAME, this.FTP_PASSWORD, this.FTP_BASEPATH, path, newFileName, filename.getInputStream());if(flag){map.put("error", 0);//http://192.168.37.137/yyyy/MM/dd/newFileNamemap.put("url", this.HTTP_BASE_PATH+path+newFileName);}else{map.put("error", 1);map.put("message","上传失败");}} catch (IOException e) {map.put("error", 1);map.put("message","上传失败");e.printStackTrace();}return map;}
}
controller:
package com.zxw.web.controller;import java.util.Map;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;import com.zxw.commons.JsonUtils;
import com.zxw.service.PicUploadService;/*** 图片上传Controller* @author Administrator**/
@Controller
@RequestMapping("/pic")
public class PicUploadController {@Autowiredprivate PicUploadService picUploadService;/*** 图片上传*/@RequestMapping("/upload")@ResponseBodypublic String fileUpload(MultipartFile fileName){Map<String, Object> map = this.picUploadService.fileUpload(fileName);return JsonUtils.objectToJson(map);}
}
package com.zxw.web.controller;import java.util.HashMap;
import java.util.Map;import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;import com.zxw.commons.JsonUtils;/*** 内容Controller* @author Administrator**/
@Controller
@RequestMapping("/content")
public class ContentController {/*** 内容保存*/@RequestMapping(value="/save",produces=MediaType.APPLICATION_JSON_VALUE)@ResponseBodypublic String saveContent(String desc){System.out.println(desc);Map<String, Object> map = new HashMap<>();map.put("status",200);return JsonUtils.objectToJson(map);}
}
结果: