下载插件:
http://pandao.github.io/editor.md/
将下载的插件解压拷贝进项目中
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!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}/res/editor-md-master/css/editormd.css" />
<script type="text/javascript" src="${ pageContext.request.contextPath }/res/js/jquery-2.1.4.min.js"></script>
<script src="${pageContext.request.contextPath}/res/editor-md-master/editormd.min.js"></script>
<script type="text/javascript">
$(function(){
var testEditor = editormd({
id: "test-editormd",
height: 640,
width: "100%",
placeholder : "Markdown编辑器",
path: "${pageContext.request.contextPath}/res/editor-md-master/lib/",
toolbarIcons: function () {
// Or return editormd.toolbarModes[name]; // full, simple, mini
// Using "||" set icons align right.
return ["undo", "redo", "|", "watch", "fullscreen", "preview"]
},
//toolbar : false, // 关闭工具栏
codeFold: true,
searchReplace: true,
saveHTMLToTextarea: true, // 保存 HTML 到 Textarea
htmlDecode: "style,script,iframe|on*", // 开启 HTML 标签解析,为了安全性,默认不开启
emoji: true,
taskList: true,
tocm: true, // Using [TOCM]
tex: true, // 开启科学公式 TeX 语言支持,默认关闭
//previewCodeHighlight : false, // 关闭预览窗口的代码高亮,默认开启
flowChart: true, // 疑似 Sea.js与 Raphael.js 有冲突,必须先加载 Raphael.js ,Editor.md 才能在 Sea.js 下正常进行;
sequenceDiagram: true, // 同上
//dialogLockScreen : false, // 设置弹出层对话框不锁屏,全局通用,默认为 true
//dialogShowMask : false, // 设置弹出层对话框显示透明遮罩层,全局通用,默认为 true
//dialogDraggable : false, // 设置弹出层对话框不可拖动,全局通用,默认为 true
//dialogMaskOpacity : 0.4, // 设置透明遮罩层的透明度,全局通用,默认值为 0.1
//dialogMaskBgColor : "#000", // 设置透明遮罩层的背景颜色,全局通用,默认为 #fff
imageUpload: true,
imageFormats: ["jpg", "jpeg", "gif", "png", "bmp", "webp"],
imageUploadURL: "{:url('api/uploader/uploadEditorImg?pic_type=10')}",
onload: function () {
this.on('paste', function () {
console.log(1);
});
},
onpreviewing : function() {
this.watch();
console.log("onpreviewing =>", this, this.id, this.settings);
// on previewing you can custom css .editormd-preview-active
},
onpreviewed : function() {
console.log("onpreviewed =>", this, this.id, this.settings);
this.unwatch();
}
});
/**
* 上传图片
*/
$("#test-editormd").on('paste', function (ev) {
var data = ev.clipboardData;
var items = (event.clipboardData || event.originalEvent.clipboardData).items;
for (var index in items) {
var item = items[index];
if (item.kind === 'file') {
var blob = item.getAsFile();
var reader = new FileReader();
reader.onload = function (event) {
var base64 = event.target.result;
console.log(base64);
//ajax上传图片
$.ajax({
url : "${pageContext.request.contextPath}/topic/uploadimg",
type : 'post',
data : {'base':base64},
async : true,
dataType: 'json',
success : function (res) {
if (res.code === 1) {
//新一行的图片显示
testEditor.insertValue("\n![" + "image.png" + "](${pageContext.request.contextPath}/" + res.path + ")");
}
},
error : function(){
alert('图片上传错误');
}
});
}; // data url!
var url = reader.readAsDataURL(blob);
}
}
});
})
</script>
</head>
<body>
<form action="${ pageContext.request.contextPath }/article/addArticle">
<div class="editormd" id="test-editormd">
<textarea class="editormd-markdown-textarea" name="topic_markdown_content" id = "topic_markdown_content">${topic.topic_markdown_content}</textarea>
</div>
<button>提交</button>
</form>
</body>
</html>
解密后保存工具类
package com.neuedu.util;
import java.io.FileOutputStream;
import java.io.OutputStream;
import sun.misc.BASE64Decoder;
public class picEncode {
/**
* @Description: 将base64编码字符串转换为图片
* @Author:
* @CreateTime:
* @param imgStr
* base64编码字符串
* @param path
* 图片路径-具体到文件
* @return
*/
public static boolean generateImage(String imgStr, String path) {
if (imgStr == null)
return false;
BASE64Decoder decoder = new BASE64Decoder();
try {
// 解密
byte[] b = decoder.decodeBuffer(imgStr);
// 处理数据
for (int i = 0; i < b.length; ++i) {
if (b[i] < 0) {
b[i] += 256;
}
}
OutputStream out = new FileOutputStream(path);
out.write(b);
out.flush();
out.close();
return true;
} catch (Exception e) {
return false;
}
}
}
实体类,用来响应页面请求
package com.neuedu.util;
public class imgUploadBackData {
private String path;
private int code;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
}
Controller或Servlet
package com.neuedu.servlet;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.alibaba.fastjson.JSON;
import com.neuedu.util.imgUploadBackData;
import com.neuedu.util.picEncode;
@WebServlet("/topic/uploadimg")
public class UploadImgServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String strTemp = request.getParameter("base");
System.out.println(strTemp);
strTemp = strTemp.replace("data:image/png;base64,","");
// String strPath = this.getClass().getClassLoader().getResource("/../../upload").getPath();
String strPath = request.getServletContext().getRealPath(File.separator+"upload");
String strUUid = UUID.randomUUID().toString();
System.out.println(strPath);
File file = new File(strPath);
if(!file.exists())
{
file.mkdirs();
}
String strSavePath = strPath+File.separator+strUUid+".jpg";
picEncode.generateImage(strTemp,strSavePath);
imgUploadBackData iubd = new imgUploadBackData();
iubd.setPath("upload"+File.separator+strUUid+".jpg");
iubd.setCode(1);
String strJson = JSON.toJSONString(iubd);
response.getWriter().println(strJson);
}
}
提交表单时可以观察请求体中的参数,会发现内容包含两部分,一部分是markdown语法部分,方便发布者修改文章,还有一部分是markdown渲染出的html部分,是作为展示的,所以,对应数据库中应该也有两个字段支持。