本篇文章进行二次更新操作,完善了上传图片功能 ,各位只需要将我下方创建的两个servlet的拷贝到你们的servlet里去。另外在修改一下js代码,如图:
今日课堂无聊,简单写了些前台,顺便给大家说说富文本编辑器的使用教程
对于分类描述,我采用了富文本编辑器~KingEditer的插件。
什么是富文本编辑器?
1.搭建富文本编辑器
去KingEditor官网去下载KingEditor文件 kingeditor网址链接: http://kindeditor.net/demo.php [不过要翻墙]
或者直接CSDNhttps://download.csdn.net/download/kese7952/10838028
下载下来解压,把文件放入java项目中
下载解压后,如下图:
我是在WebContent或者WebRoot下新建了一个文件夹Folder,命名为:kindEditer,将lang
,plugins
,themes
,kindediteror-all.js
,kindediteror-all-min.js
拷贝到kindEditer文件夹下了。如图:
在WebContent里新建了一个页面,命名为header.jsp
,在其中引入了部分官方提供模板代码,(大家也可以选择拷贝我的代码:)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> <link rel="stylesheet" href="${pageContext.request.contextPath}/css/main.css" /> <!--想使用富文本编辑器,需要引入下面三条--> <link rel="stylesheet" href="${pageContext.request.contextPath}/kindEditor/themes/default/default.css" /> <script charset="utf-8" src="${pageContext.request.contextPath}/kindEditor/kindeditor-all-min.js"></script> <script charset="utf-8" src="${pageContext.request.contextPath}/kindEditor/lang/zh_CN.js"></script> <!-- <script> //简单模式初始化 //简单模式 注意:下方中的content属性值要与textarea的name属性值相同才可以 var editor; KindEditor.ready(function(K) { editor = K.create('textarea[name="content"]', { resizeType : 1, allowPreviewEmoticons : false, allowImageUpload : false, items : [ 'fontname', 'fontsize', '|', 'forecolor', 'hilitecolor', 'bold', 'italic', 'underline', 'removeformat', '|', 'justifyleft', 'justifycenter', 'justifyright', 'insertorderedlist', 'insertunorderedlist', '|', 'emoticons', 'image', 'link'] }); }); </script> --> <script> //默认模式 注意:下方中的content属性值要与textarea的name属性值相同才可以 var editor; KindEditor.ready(function(K) { editor = K.create('textarea[name="content"]', { allowFileManager : true, uploadJson:'${pageContext.request.contextPath}/kindeditorUploadServlet', fileManagerJson:'${pageContext.request.contextPath}/kindeditorFileManagerServlet' }); K('input[name=getHtml]').click(function(e) { alert(editor.html()); }); K('input[name=isEmpty]').click(function(e) { alert(editor.isEmpty()); }); K('input[name=getText]').click(function(e) { alert(editor.text()); }); K('input[name=selectedHtml]').click(function(e) { alert(editor.selectedHtml()); }); K('input[name=setHtml]').click(function(e) { editor.html('<h3>Hello KindEditor</h3>'); }); K('input[name=setText]').click(function(e) { editor.text('<h3>Hello KindEditor</h3>'); }); K('input[name=insertHtml]').click(function(e) { editor.insertHtml('<strong>插入HTML</strong>'); }); K('input[name=appendHtml]').click(function(e) { editor.appendHtml('<strong>添加HTML</strong>'); }); K('input[name=clear]').click(function(e) { editor.html(''); }); }); </script> </head>
代码中,我涉及到了两种模式:(二选一)
第一种简约模式,效果如图:
第二种默认的富文本编辑模式,效果如图:
这里,我选择的是第二种模式。【即,把简约模式进行了注释】
以下是我的代码示例:
步骤一:新建一个jsp页面,起名为addCategory.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ include file="/header.jsp" %> <br/> <center> <form action="${pageContext.request.contextPath}/CategoryServlet?op=addCategory" method="post" > <table> <tr> <td>分类名称:</td> <td> <input type="text" name="name" > </td> </tr> <tr> <td>分类描述:</td> <td><textarea id="mul_input" name="description" style="width:700px;height:200px;visibility:hidden;display: block;"></textarea> </tr> <tr class="input_control"> <td colspan="2"> <input type="submit" value="添加图书" id="btn1" > </td> </tr> </table> </form> </center>
首先我是在addCategory.jsp的开头就引进了一个header页面,header页面代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> <link rel="stylesheet" href="${pageContext.request.contextPath}/kingEditer/themes/default/default.css" /> <link rel="stylesheet" href="${pageContext.request.contextPath}/css/main.css" /> <script charset="utf-8" src="${pageContext.request.contextPath}/kingEditer/kindeditor-all-min.js"></script> <script charset="utf-8" src="${pageContext.request.contextPath}/kingEditer/lang/zh_CN.js"></script> <!-- <script> //简单模式初始化 var editor; KindEditor.ready(function(K) { editor = K.create('textarea[name="description"]', { resizeType : 1, allowPreviewEmoticons : false, allowImageUpload : false, items : [ 'fontname', 'fontsize', '|', 'forecolor', 'hilitecolor', 'bold', 'italic', 'underline', 'removeformat', '|', 'justifyleft', 'justifycenter', 'justifyright', 'insertorderedlist', 'insertunorderedlist', '|', 'emoticons', 'image', 'link'] }); }); </script> --> <script> //默认模式 var editor; KindEditor.ready(function(K) { editor = K.create('textarea[name="description"]', { allowFileManager : true }); K('input[name=getHtml]').click(function(e) { alert(editor.html()); }); K('input[name=isEmpty]').click(function(e) { alert(editor.isEmpty()); }); K('input[name=getText]').click(function(e) { alert(editor.text()); }); K('input[name=selectedHtml]').click(function(e) { alert(editor.selectedHtml()); }); K('input[name=setHtml]').click(function(e) { editor.html('<h3>Hello KindEditor</h3>'); }); K('input[name=setText]').click(function(e) { editor.text('<h3>Hello KindEditor</h3>'); }); K('input[name=insertHtml]').click(function(e) { editor.insertHtml('<strong>插入HTML</strong>'); }); K('input[name=appendHtml]').click(function(e) { editor.appendHtml('<strong>添加HTML</strong>'); }); K('input[name=clear]').click(function(e) { editor.html(''); }); }); </script> </head> <body> <h1>欢迎来到趣读书屋</h1> <br/> <br/> <ul> <li> <a href="">添加分类</a> </li> <li> <a href="">添加图书</a> </li> <li> <a href="">用户注册</a> </li> <li> <a href="">用户登录</a> </li> <li> <a href="">购物车</a> </li> <li> <a href="">我的订单</a> </li> </ul> <br/> <br/> <hr/>
【2019.06】完善上传功能实现
1. 上传Jar包
commons-collections-3.2.1.jar
commons-fileupload-1.3.1.jar
commons-io-2.4.jar
json_simple-1.1.jar
关于如何下载jar包,可以查看https://mryang.blog.csdn.net/article/details/91410923
2. 创建两个Servlet
2.1 第一个Servlet命名为 KindeditorFileManagerServlet
package cn.javabs.school.servlet; import org.json.simple.JSONObject; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.util.Collections; import java.util.Comparator; import java.text.SimpleDateFormat; import java.util.*; @WebServlet("/kindeditorFileManagerServlet") public class KindeditorFileManagerServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request,response); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); /** * KindEditor JSP * * 本JSP程序是演示程序,建议不要直接在实际项目中使用。 如果您确定直接使用本程序,使用之前请仔细确认相关安全设置。 * */ // 根目录路径,可以指定绝对路径,比如 /var/www/attached/ String rootPath = getServletContext().getRealPath("/") + "attached/"; // 根目录URL,可以指定绝对路径,比如 http://www.yoursite.com/attached/ String rootUrl = request.getContextPath() + "/attached/"; // 图片扩展名 String[] fileTypes = new String[] { "gif", "jpg", "jpeg", "png", "bmp" }; String dirName = request.getParameter("dir"); if (dirName != null) { if (!Arrays.<String> asList( new String[] { "image", "flash", "media", "file" }) .contains(dirName)) { out.println("Invalid Directory name."); return; } rootPath += dirName + "/"; rootUrl += dirName + "/"; File saveDirFile = new File(rootPath); if (!saveDirFile.exists()) { saveDirFile.mkdirs(); } } // 根据path参数,设置各路径和URL String path = request.getParameter("path") != null ? request .getParameter("path") : ""; String currentPath = rootPath + path; String currentUrl = rootUrl + path; String currentDirPath = path; String moveupDirPath = ""; if (!"".equals(path)) { String str = currentDirPath.substring(0, currentDirPath.length() - 1); moveupDirPath = str.lastIndexOf("/") >= 0 ? str.substring(0, str .lastIndexOf("/") + 1) : ""; } // 排序形式,name or size or type String order = request.getParameter("order") != null ? request .getParameter("order").toLowerCase() : "name"; // 不允许使用..移动到上一级目录 if (path.indexOf("..") >= 0) { out.println("Access is not allowed."); return; } // 最后一个字符不是/ if (!"".equals(path) && !path.endsWith("/")) { out.println("Parameter is not valid."); return; } // 目录不存在或不是目录 File currentPathFile = new File(currentPath); if (!currentPathFile.isDirectory()) { out.println("Directory does not exist."); return; } // 遍历目录取的文件信息 List<Hashtable> fileList = new ArrayList<Hashtable>(); if (currentPathFile.listFiles() != null) { for (File file : currentPathFile.listFiles()) { Hashtable<String, Object> hash = new Hashtable<String, Object>(); String fileName = file.getName(); if (file.isDirectory()) { hash.put("is_dir", true); hash.put("has_file", (file.listFiles() != null)); hash.put("filesize", 0L); hash.put("is_photo", false); hash.put("filetype", ""); } else if (file.isFile()) { String fileExt = fileName.substring( fileName.lastIndexOf(".") + 1).toLowerCase(); hash.put("is_dir", false); hash.put("has_file", false); hash.put("filesize", file.length()); hash.put("is_photo", Arrays.<String> asList(fileTypes) .contains(fileExt)); hash.put("filetype", fileExt); } hash.put("filename", fileName); hash.put("datetime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(file .lastModified())); fileList.add(hash); } } if ("size".equals(order)) { Collections.sort(fileList, new SizeComparator()); } else if ("type".equals(order)) { Collections.sort(fileList, new TypeComparator()); } else { Collections.sort(fileList, new NameComparator()); } JSONObject result = new JSONObject(); result.put("moveup_dir_path", moveupDirPath); result.put("current_dir_path", currentDirPath); result.put("current_url", currentUrl); result.put("total_count", fileList.size()); result.put("file_list", fileList); response.setContentType("application/json; charset=UTF-8"); out.println(result.toJSONString()); out.close(); } public class NameComparator implements Comparator { public int compare(Object a, Object b) { Hashtable hashA = (Hashtable) a; Hashtable hashB = (Hashtable) b; if (((Boolean) hashA.get("is_dir")) && !((Boolean) hashB.get("is_dir"))) { return -1; } else if (!((Boolean) hashA.get("is_dir")) && ((Boolean) hashB.get("is_dir"))) { return 1; } else { return ((String) hashA.get("filename")) .compareTo((String) hashB.get("filename")); } } } public class SizeComparator implements Comparator { public int compare(Object a, Object b) { Hashtable hashA = (Hashtable) a; Hashtable hashB = (Hashtable) b; if (((Boolean) hashA.get("is_dir")) && !((Boolean) hashB.get("is_dir"))) { return -1; } else if (!((Boolean) hashA.get("is_dir")) && ((Boolean) hashB.get("is_dir"))) { return 1; } else { if (((Long) hashA.get("filesize")) > ((Long) hashB .get("filesize"))) { return 1; } else if (((Long) hashA.get("filesize")) < ((Long) hashB .get("filesize"))) { return -1; } else { return 0; } } } } public class TypeComparator implements Comparator { public int compare(Object a, Object b) { Hashtable hashA = (Hashtable) a; Hashtable hashB = (Hashtable) b; if (((Boolean) hashA.get("is_dir")) && !((Boolean) hashB.get("is_dir"))) { return -1; } else if (!((Boolean) hashA.get("is_dir")) && ((Boolean) hashB.get("is_dir"))) { return 1; } else { return ((String) hashA.get("filetype")) .compareTo((String) hashB.get("filetype")); } } } }
2.2 第二个Servlet命名为 KindeditorUploadServlet
package cn.javabs.school.servlet; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileItemFactory; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.json.simple.JSONObject; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.util.*; @WebServlet("/kindeditorUploadServlet") public class KindeditorUploadServlet extends HttpServlet { public KindeditorUploadServlet() { super(); } private String getError(String message) { JSONObject obj = new JSONObject(); obj.put("error", 1); obj.put("message", message); return obj.toJSONString(); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /** * KindEditor JSP * * 本JSP程序是演示程序,建议不要直接在实际项目中使用。 如果您确定直接使用本程序,使用之前请仔细确认相关安全设置。 * */ request.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8"); PrintWriter out = response.getWriter(); // 文件保存目录路径 String savePath = getServletContext().getRealPath("/") + "attached/"; System.out.println("savePath:" + savePath); // 文件保存目录URL String saveUrl = request.getContextPath() + "/attached/"; // 定义允许上传的文件扩展名 HashMap<String, String> extMap = new HashMap<String, String>(); extMap.put("image", "gif,jpg,jpeg,png,bmp"); extMap.put("flash", "swf,flv"); extMap.put("media", "swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb"); extMap.put("file", "doc,docx,xls,xlsx,ppt,htm,html,txt,zip,rar,gz,bz2"); // 最大文件大小 long maxSize = 1000000; response.setContentType("application/json; charset=UTF-8"); if (!ServletFileUpload.isMultipartContent(request)) { out.println(getError("请选择文件。")); return; } // 检查目录 File uploadDir = new File(savePath); if (!uploadDir.isDirectory()) { uploadDir.mkdirs(); // out.println(getError("上传目录不存在。")); return; } // 检查目录写权限 if (!uploadDir.canWrite()) { out.println(getError("上传目录没有写权限。")); return; } String dirName = request.getParameter("dir"); if (dirName == null) { dirName = "image"; } if (!extMap.containsKey(dirName)) { out.println(getError("目录名不正确。")); return; } // 创建文件夹 savePath += dirName + "/"; saveUrl += dirName + "/"; File saveDirFile = new File(savePath); if (!saveDirFile.exists()) { saveDirFile.mkdirs(); } SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); String ymd = sdf.format(new Date()); savePath += ymd + "/"; saveUrl += ymd + "/"; File dirFile = new File(savePath); if (!dirFile.exists()) { dirFile.mkdirs(); } FileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload upload = new ServletFileUpload(factory); upload.setHeaderEncoding("UTF-8"); try { List items = upload.parseRequest(request); Iterator itr = items.iterator(); while (itr.hasNext()) { FileItem item = (FileItem) itr.next(); String fileName = item.getName(); long fileSize = item.getSize(); if (!item.isFormField()) { // 检查文件大小 if (item.getSize() > maxSize) { out.println(getError("上传文件大小超过限制。")); return; } // 检查扩展名 String fileExt = fileName.substring( fileName.lastIndexOf(".") + 1).toLowerCase(); if (!Arrays.<String> asList(extMap.get(dirName).split(",")) .contains(fileExt)) { out.println(getError("上传文件扩展名是不允许的扩展名。\n只允许" + extMap.get(dirName) + "格式。")); return; } SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss"); String newFileName = df.format(new Date()) + "_" + new Random().nextInt(1000) + "." + fileExt; try { File uploadedFile = new File(savePath, newFileName); item.write(uploadedFile); } catch (Exception e) { out.println(getError("上传文件失败。")); return; } JSONObject obj = new JSONObject(); obj.put("error", 0); obj.put("url", saveUrl + newFileName); out.println(obj.toJSONString()); } } } catch (FileUploadException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } }
3. 在jsp中引入以下代码
<!-- 以下是kindEditor 需要用的静态资源 --> <link rel="stylesheet" href="${pageContext.request.contextPath}/admin/resource/kindEditor/themes/default/default.css" /> <script charset="utf-8" src="${pageContext.request.contextPath}/admin/resource/kindEditor/kindeditor-all-min.js"></script> <script charset="utf-8" src="${pageContext.request.contextPath}/admin/resource/kindEditor/lang/zh-CN.js"></script> <script type="text/javascript"> $(function () { $("#saveUpdateForm").validate({debug:false}); }); </script> <script> //默认模式 注意:下方中的content属性值要与textarea的name属性值相同才可以 var editor; KindEditor.ready(function(K) { editor = K.create('textarea[name="content"]', { allowFileManager : true, uploadJson:'${pageContext.request.contextPath}/kindeditorUploadServlet', fileManagerJson:'${pageContext.request.contextPath}/kindeditorFileManagerServlet' }); K('input[name=getHtml]').click(function(e) { alert(editor.html()); }); K('input[name=isEmpty]').click(function(e) { alert(editor.isEmpty()); }); K('input[name=getText]').click(function(e) { alert(editor.text()); }); K('input[name=selectedHtml]').click(function(e) { alert(editor.selectedHtml()); }); K('input[name=setHtml]').click(function(e) { editor.html('<h3>Hello KindEditor</h3>'); }); K('input[name=setText]').click(function(e) { editor.text('<h3>Hello KindEditor</h3>'); }); K('input[name=insertHtml]').click(function(e) { editor.insertHtml('<strong>插入HTML</strong>'); }); K('input[name=appendHtml]').click(function(e) { editor.appendHtml('<strong>添加HTML</strong>'); }); K('input[name=clear]').click(function(e) { editor.html(''); }); }); </script> <body> <label>文章正文</label> <textarea id="entityContent" name="content" style="width:800px;height:400px;visibility:hidden;" data-rule-required="true"> </textarea> </body>
注意:
因为我在设计分类实体的属性时,采用了描述的单词[description],所以我在表单中的属性值也是description,所以在header中的content需要改成description,才会有效!!!
此时的富文本编辑器就实现了。
但是我还加入一些css样式,在WebContent下创建一个文件夹,命名为css,并且在css文件夹中船舰了一个文件,命名为main.css
代码如下:
@CHARSET "UTF-8"; body { margin: 20 auto; font-size : 12px; text-align: center; font-size: 12px; } /* 导航栏 */ ul { list-style: none; margin-left: 280px; } /*无序列表*/ li { float: left; /* 向左悬浮起来 */ height: 30px;/* 告诉为30像素 */ width: 100px;/* 宽度为100像素 */ color: white;/* 向左悬浮起来 */ background-color: red;/* 背景颜色为红色 */ margin-left: 3px;/* 每个li向左空开3个像素 */ border-radius: 15px 15px 0 0;/* 属于css3的样式: 加入圆角边框的形式;上边出现圆角弧度,下边没有弧度。若想都设置为带有弧度,可以全部填写15px */ } /* 未点击时的超链接 */ li a:LINK { font-size: 14px;/* 字体大小 */ line-height: 32px; /* 字体行高 */ text-decoration: none; /* 去除下划线 */ color: #efefef; /* 字体颜色 */ } /* 鼠标悬浮时的超链接 */ li a:hover { background-color: #e151ff; color: #efefef; } /* 添加分类 */ table { margin: 20 auto; font-size: 14px; text-align: center; } /*添加分类的按钮*/ #btn1 { width: 160px; margin: 20px auto; box-sizing: border-box; text-align: center; border-radius: 4px; border: 1px solid #c8cccf; color: #6a6f77; -web-kit-appearance: none; -moz-appearance: none; display: block; outline: 0; padding: 0 1em; text-decoration: none; height: 2.7em; width: 30%; } .form-input { -web-kit-appearance: none; -moz-appearance: none; font-size: 1.4em; height: 2.7em; border-radius: 4px; border: 1px solid #c8cccf; color: #6a6f77; } input[type="text"], #btn2 { box-sizing: border-box; text-align: center; height: 2.7em; font-size: 1.4em; border-radius: 4px; border: 1px solid #c8cccf; color: #6a6f77; -web-kit-appearance: none; -moz-appearance: none; display: block; outline: 0; padding: 0 1em; text-decoration: none; width: 100%; } input[type="text"]:focus { border: 1px solid #ff7496; }
下载代码
https://github.com/yangsir1688/kindeditor-fileUploadDemo
分享是快乐的,也见证了个人成长历程,文章大多都是工作经验总结以及平时学习积累,基于自身认知不足之处在所难免,也请大家指正,共同进步。