kindeditor在以前已經用過,如今在springboot項目中使用。而且也在裏面使用了圖片上傳以及回顯等功能。javascript
其實主要的功能是圖片的處理:kindeditor對輸入的內容會做爲html標籤處理,對於image的作法是先將圖片傳到後臺服務器,而後上傳成功以後回傳圖片的URL,以後內容中增長<img src='url'>進行回顯,固然保存到數據庫也是img標籤進行保存的。css
下面的代碼涉及到了:Restful風格的請求、SpringMVC文件的上傳、不配置虛擬路徑的前提下請求圖片資源、kindeditor、thymeleaf模板的使用。html
package cn.qs.controller.user; import java.io.File; import java.io.FileInputStream; import java.util.Date; import java.util.HashMap; import java.util.Map; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; import cn.qs.bean.user.Blogpicture; import cn.qs.service.user.BlogPictureService; import cn.qs.utils.FileHandleUtil; import cn.qs.utils.UUIDUtil; @Controller @RequestMapping("blogPicture") public class BlogPictureController { private static final Logger logger = LoggerFactory.getLogger(BlogPictureController.class); @Autowired private BlogPictureService blogPictureService; /** * Restful風格獲取圖片 * * @param request * @param response * @param pictureId */ @RequestMapping("/getPicture/{pictureId}") public void getPicture(HttpServletRequest request, HttpServletResponse response, @PathVariable() String pictureId) { FileInputStream in = null; ServletOutputStream outputStream = null; try { String picturePath = blogPictureService.getPicturePathByPictureId(pictureId); File fileByName = FileHandleUtil.getFileByName(picturePath); in = new FileInputStream(fileByName); outputStream = response.getOutputStream(); IOUtils.copyLarge(in, outputStream); } catch (Exception e) { e.printStackTrace(); } finally { IOUtils.closeQuietly(in); IOUtils.closeQuietly(outputStream); } } /** * 圖片上傳 * * @param imgFile * @return */ @RequestMapping("/uploadPicture") @ResponseBody public Map<String, Object> uploadPicture(MultipartFile imgFile) { Map<String, Object> result = new HashMap<String, Object>(); result.put("error", 1); if (imgFile == null) { result.put("message", "文件沒接到"); return result; } logger.debug("file -> {},viewId ->{}", imgFile.getOriginalFilename()); String fileOriName = imgFile.getOriginalFilename();// 獲取原名稱 String fileNowName = UUIDUtil.getUUID2() + "." + FilenameUtils.getExtension(fileOriName);// 生成惟一的名字 try { FileHandleUtil.uploadSpringMVCFile(imgFile, fileNowName); } catch (Exception e) { logger.error("uploadPicture error", e); return result; } String id = UUIDUtil.getUUID(); Blogpicture blogpicture = new Blogpicture(); blogpicture.setCreatetime(new Date()); blogpicture.setId(id); blogpicture.setPath(fileNowName); blogpicture.setOriginname(fileNowName); blogPictureService.insert(blogpicture); result.put("error", 0); result.put("url", "/blogPicture/getPicture/" + id); return result; } }
圖片上傳:參數接受名字必須是imgFile,不然接收不到文件。收到文件以後先生成一個全局惟一的名稱而後保存到本地,並保存到數據庫以後返回一個圖片的URL例如: /blogPicture/getPicture/94995b51-901c-44e9-87ec-12c109098f5ehtml5
圖片獲取:經過restful風格的請求將圖片的ID傳到後臺,根據ID查詢到圖片的路徑,而後調用IOUtils將文件流回傳回去實現圖片的src請求顯示拖。java
FileHandleUtil類是圖片保存以及獲取,保存到本地的固定文件夾下面。jquery
package cn.qs.utils; import java.io.File; import java.util.Locale; import java.util.ResourceBundle; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.web.multipart.MultipartFile; public class FileHandleUtil { public static final String LANGUAGE = "zh"; public static final String COUNTRY = "CN"; private static String getProperties(String baseName, String section) { String retValue = ""; try { Locale locale = new Locale(LANGUAGE, COUNTRY); ResourceBundle rb = ResourceBundle.getBundle(baseName, locale); retValue = (String) rb.getObject(section); } catch (Exception e) { } return retValue; } public static String getValue(String fileName, String key) { String value = getProperties(fileName, key); return value; } public static boolean deletePlainFile(String propertiesFileName, String fileName) { if (fileName == null) { return false; } String fileDir = StringUtils.defaultIfBlank(FileHandleUtil.getValue("path", "picture"), "E:/picture/"); try { FileUtils.deleteQuietly(new File(fileDir + fileName)); } catch (Exception e) { return false; } return true; } public static boolean uploadSpringMVCFile(MultipartFile multipartFile, String fileName) throws Exception { String fileDir = StringUtils.defaultIfBlank(FileHandleUtil.getValue("path", "picture"), "E:/picture/"); if (!new File(fileDir).exists()) { new File(fileDir).mkdirs(); } multipartFile.transferTo(new File(fileDir + fileName));// 保存文件 return true; } public static File getFileByName(String path) { String fileDir = StringUtils.defaultIfBlank(FileHandleUtil.getValue("path", "picture"), "E:/picture/"); return new File(fileDir+path); } }
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"/> <title>歡迎頁面-X-admin2.0</title> <meta name="renderer" content="webkit"/> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/> <meta name="viewport" content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi" /> <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" /> <link rel="stylesheet" th:href="${#httpServletRequest.getContextPath()+'/static/x-admin/css/font.css'}"/> <link rel="stylesheet" th:href="${#httpServletRequest.getContextPath()+'/static/x-admin/css/xadmin.css'}"/> <script type="text/javascript" th:src="${#httpServletRequest.getContextPath()+'/static/js/jquery.min.js'}" charset="utf-8"></script> <script type="text/javascript" th:src="${#httpServletRequest.getContextPath()+'/static/x-admin/lib/layui/layui.js'}" charset="utf-8"></script> <script type="text/javascript" th:src="${#httpServletRequest.getContextPath()+'/static/x-admin/js/xadmin.js'}"></script> <!-- kindeditor相關 --> <link rel="stylesheet" th:href="${#httpServletRequest.getContextPath()+'/static/kindeditor/themes/default/default.css'}" /> <link rel="stylesheet" th:href="${#httpServletRequest.getContextPath()+'/static/kindeditor/plugins/code/prettify.css'}" /> <script charset="utf-8" th:src="${#httpServletRequest.getContextPath()+'/static/kindeditor/kindeditor-all.js'}"></script> <script charset="utf-8" th:src="${#httpServletRequest.getContextPath()+'/static/kindeditor/lang/zh-CN.js'}"></script> <script> var editor; KindEditor.ready(function(K) { editor = K.create('textarea[name="contentEditor"]', { resizeType : 1, allowPreviewEmoticons : false, uploadJson : '/blogPicture/uploadPicture.html', allowImageUpload : true, pasteType : 0, //設置可否粘貼 items : [ 'fontname', 'fontsize', '|', 'forecolor', 'hilitecolor', 'bold', 'italic', 'underline', 'removeformat', '|', 'justifyleft', 'justifycenter', 'justifyright', 'insertorderedlist', 'insertunorderedlist', '|', 'emoticons', 'image', 'link','fullscreen'] }); }); </script> <!-- 讓IE8/9支持媒體查詢,從而兼容柵格 --> <!--[if lt IE 9]> <script src="https://cdn.staticfile.org/html5shiv/r29/html5.min.js"></script> <script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script> <![endif]--> </head> <body> <div class="x-body layui-anim layui-anim-up"> <form class="layui-form"> <div class="layui-form-item"> <label for="L_email" class="layui-form-label"> <span class="x-red">*</span>博客標題 </label> <div class="layui-input-inline"> <input type="text" id="L_blogtitle" name="blogtitle" lay-verify="required" autocomplete="off" class="layui-input"/> </div> </div> <div class="layui-form-item"> <label for="L_email" class="layui-form-label"> <span class="x-red">*</span>內容 </label> <div class="layui-input-inline"> <textarea name="contentEditor" id="test" cols="100" rows="8" style="width:700px;height:200px;visibility:hidden;"></textarea> </div> </div> <div class="layui-form-item"> <label for="L_repass" class="layui-form-label"> </label> <button class="layui-btn" lay-filter="add" lay-submit=""> 增長 </button> </div> </form> </div> </body> <script> /*<![CDATA[*/ layui.use(['form','layer'], function(){ $ = layui.jquery; var form = layui.form ,layer = layui.layer; //監聽提交 form.on('submit(add)', function(data){ var data = { "blogtitle":$('[name="blogtitle"]').val(), "content":editor.html() } //異步提交數據 $.post("/blog/doAddBlog.html",data,function(response){ if(response.success == true){ layer.msg("增長成功", {icon: 6},function () { // 得到frame索引 var index = parent.layer.getFrameIndex(window.name); //關閉當前frame parent.layer.close(index); // 父頁面刷新 parent.location.reload(); }); }else{ layer.alert(response.msg); } }); return false; }); }); /*]]>*/ </script> </html>
界面以下:git
最終生成的內容保存到數據庫以後以下:github
<p> 測試 </p> <p> <img src="http://localhost:8088/static/kindeditor/plugins/emoticons/images/20.gif" border="0" alt="" /> </p> <p> <img src="/blogPicture/getPicture/efe5134f-8a41-4e75-9108-6ab045979db6" alt="" /> </p>
最終通過代碼處理後在界面顯示以下:web
@RequestMapping("/getBlogdetail/{blogId}") public String getBlogdetail(ModelMap map, @PathVariable() Integer blogId, HttpServletRequest request) { Blog blog = blogService.getBlogdetail(blogId); // 獲取當前用戶 HttpSession session = request.getSession(); User user = (User) session.getAttribute("user"); String username = user.getUsername(); String blogUsername = StringUtils.defaultIfBlank(blog.getBlogblank(), "admin"); if (blogUsername.equals(username)) { map.put("blog", blog); } else { map.put("blog", new Blog()); } return "blogDetail"; }
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"/> <title th:text="${blog.blogtitle}"></title> <meta name="renderer" content="webkit"/> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/> <meta name="viewport" content="width=device-width,user-scalable=yes, minimum-scale=0.4, initial-scale=0.8,target-densitydpi=low-dpi" /> <link rel="shortcut icon" href="/static/x-admin/favicon.ico" type="image/x-icon" /> <link rel="stylesheet" th:href="${#httpServletRequest.getContextPath()+'/static/x-admin/css/font.css'}"/> <link rel="stylesheet" th:href="${#httpServletRequest.getContextPath()+'/static/x-admin/css/xadmin.css'}"/> <script type="text/javascript" src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script> <script type="text/javascript" th:src="${#httpServletRequest.getContextPath()+'/static/x-admin/lib/layui/layui.all.js'}" charset="utf-8"></script> <script type="text/javascript" th:src="${#httpServletRequest.getContextPath()+'/static/x-admin/js/xadmin.js'}"></script> <span th:if="${session.user.username} eq 'admin'"> <script> var admin = true; </script> </span> <style type="text/css"> body{ text-align:center; background-color: #dcdcdc; } #container{ text-align:left; margin:0 auto; width: 80%; background-color: #fff; } </style> </head> <body class="layui-anim layui-anim-up"> <div id="container"> <center> <h1 th:text="${'標題:'+blog.blogtitle}"></h1> <h2 th:text="${'所屬人'+blog.blogblank}"></h2> </center> <hr/> <span th:utext="${blog.content}"></span> </div> </body> </html>
補充:kindeditor可選的顯示插件有好多,以下須要的時候items裏面增長對應的選項便可spring
items : [
'source', '|', 'undo', 'redo', '|', 'preview', 'print', 'template', 'code', 'cut', 'copy', 'paste',
'plainpaste', 'wordpaste', '|', 'justifyleft', 'justifycenter', 'justifyright',
'justifyfull', 'insertorderedlist', 'insertunorderedlist', 'indent', 'outdent', 'subscript',
'superscript', 'clearhtml', 'quickformat', 'selectall', '|', 'fullscreen', '/',
'formatblock', 'fontname', 'fontsize', '|', 'forecolor', 'hilitecolor', 'bold',
'italic', 'underline', 'strikethrough', 'lineheight', 'removeformat', '|', 'image', 'multiimage',
'flash', 'media', 'insertfile', 'table', 'hr', 'emoticons', 'baidumap', 'pagebreak',
'anchor', 'link', 'unlink', '|', 'about'
]