springboot 使用kindeditor 页面跨域 图片上传 图片获取 前后分离
今天使用springboot 集成 kindeditor 本来以为挺简单 结果搞了我一天 才弄好。主要是图片上传的问题。吐槽一下 网上好多介绍说的都不完善 搞死我了。我这一篇绝对是完善的(相对比较完善。。)
1.kindeditor 下载地址:http://kindeditor.net/down.php 直接下载
下载后解压 目录如下图 里面有asp jsp php的例子。jsp已经过时了,所以想直接用html来集成【下图中的index.html Jquery,redirect.html是我后来加上去的】
2.springboot
最简单就是:start.spring.io直接生成一个简单的springboot
3.废话不多说 开始集成
3.1:首先创建一个html 我这里是index.html index.html里的内容是 jsp->demo.jsp里的内容 删掉jsp特有的东西
附加kindeditor非常简单 代码如下
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <script src="kindeditor-all-min.js"></script> <script src="lang/zh-CN.js"></script> <script src="jquery-3.1.0.min.js"></script> <title></title> </head> <body> <textarea id="txtEditor" name="content1" style="height: 300px;width: 100%;"></textarea> <button type="button" onclick="upload();">上传</button> </body> <script> var callback = "redirect.html"; var editor1; var editor = KindEditor.ready(function(K) { editor1 = K.create('textarea[name="content1"]', { cssPath : '../plugins/code/prettify.css', uploadJson : 'http://127.0.0.1:8081/upload/upmethod?callBackPath='+callback, fileManagerJson : '../jsp/file_manager_json.jsp', allowFileManager : true, afterCreate : function() { var self = this; K.ctrl(document, 13, function() { self.sync(); document.forms['example'].submit(); }); K.ctrl(self.edit.doc, 13, function() { self.sync(); document.forms['example'].submit(); }); } }); }); </script> <script src="upload.js"></script> </html>
这样我们就可以打开index看看效果了 如下图
上传图片:这里用html上传图片
首先创建redirect.html 我是直接放在项目目录下 和index.html同级 redirect.html的内容如下:
redirect.html 的作用是解决frame域的问题 这个问题搞了我很长时间。kindeditor是用frame
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>ie </title> <script type="text/javascript"> function getParameter(val) { var uri = decodeURI(window.location.search); var re = new RegExp("" + val + "=([^&?]*)", "ig"); return ((uri.match(re)) ? (uri.match(re)[0].substr(val.length + 1)) : null); } var upload_callback = function() { var error = getParameter("error"); error = parseInt(error) var dataObject; if(error==0){ var url = getParameter("url"); dataObject = {"error": error, "url": url}; }else{ var message = getParameter("message"); dataObject = {"error": error, "message": message}; } var data = JSON.stringify(dataObject) document.getElementsByTagName("body")[0].innerHTML = '<pre>' + data + '</pre>'; } </script> </head> <body onload="upload_callback();"> </body> </html>
后台项目结构如下 首先需要先把kindeditor的jar包附加到springboot项目中
主Application的内容就是原来的内容不变
主要是imgUploadController 图片上传类 内容如下
package com.example.upload.up; import java.io.File; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URLEncoder; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Random; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; @Controller @RequestMapping("/upload") public class imgUploadController { @RequestMapping("/subContent") public void getTextAreaContent(@RequestParam String context1) { String contentx = context1; System.out.println(contentx); } @ResponseBody @RequestMapping("/upmethod") public void uploadMethod(@RequestParam String callBackPath,@RequestParam(value="imgFile",required=false)MultipartFile file,HttpServletRequest request,HttpServletResponse response) throws FileUploadException, IOException { response.setContentType("text/html;charset=UTF-8"); String savePath = "D://imgSavePath/"; String saveUrl = request.getContextPath() + "/imgSavePath/"; //定义允许上传的文件扩展名 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 = 100000000; response.setContentType("text/html; charset=UTF-8"); if(!ServletFileUpload.isMultipartContent(request)){ System.out.println("请选择文件。"); response.sendRedirect(getError("请选择文件.",callBackPath)); return; } //检查目录 File uploadDir = new File(savePath); if(!uploadDir.isDirectory()){ System.out.println("上传目录不存在。"); response.sendRedirect(getError("上传目录不存在。",callBackPath)); return; } //检查目录写权限 if(!uploadDir.canWrite()){ System.out.println("上传目录没有写权限。"); response.sendRedirect(getError("上传目录没有写权限。",callBackPath)); return; } String dirName = request.getParameter("dir"); if (dirName == null) { dirName = "image"; } if(!extMap.containsKey(dirName)){ System.out.println("目录名不正确。"); response.sendRedirect(getError("目录名不正确。",callBackPath)); 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(); } String fileName = file.getOriginalFilename(); long fileSize = file.getSize(); // if (!item.isFormField()) { //检查文件大小 if(file.getSize() > maxSize){ System.out.println("上传文件大小超过限制。"); response.sendRedirect(getError("上传文件大小超过限制。",callBackPath)); return; } //检查扩展名 String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase(); if(!Arrays.<String>asList(extMap.get(dirName).split(",")).contains(fileExt)){ System.out.println("上传文件扩展名是不允许的扩展名。\n只允许" + extMap.get(dirName) + "格式。"); response.sendRedirect(getError("上传文件扩展名是不允许的扩展名。\n只允许" + extMap.get(dirName) + "格式。",callBackPath)); return; } SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss"); String newFileName = df.format(new Date()) + "_" + new Random().nextInt(1000) + "." + fileExt; try{ File uploadedFile = new File(savePath, newFileName); OutputStream os = new FileOutputStream(uploadedFile); InputStream inputStream = file.getInputStream(); byte[] buf = new byte[1024]; int length = 0; while((length = inputStream.read(buf))!=-1) { os.write(buf,0,length); } inputStream.close(); os.close(); }catch(Exception e){ System.out.println("上传文件失败。"); response.sendRedirect(getError("上传文件失败。",callBackPath)); return; } Map<String, Object> msgMap = new HashMap<String, Object>(); msgMap.put("error", 0); msgMap.put("url", ""); String urlString = ""; //根据自己实际情况做修改 urlString = "http://127.0.0.1:8020/kindeditor-4.1.11-zh-CN/kindeditor/"+callBackPath+"?error=0&url="+"http://127.0.0.1:8081/OTA/"+ymd+"/"+newFileName; response.sendRedirect(urlString); } private String getError(String message,String callBackPath) throws UnsupportedEncodingException { Map<String, Object> msg = new HashMap<String, Object>(); msg.put("error", 1); msg.put("message", message); String urlString = "http://127.0.0.1:8020/kindeditor-4.1.11-zh-CN/kindeditor/"+callBackPath+"?error=1&message="+URLEncoder.encode(message, "UTF-8"); return urlString; } }
内容写的不太完善 这不重要 重要的是后面的一段代码
我们返回内容重定向到redirect.html 并且返回数据:error 和 url 我这里在static目录下放了一张图片1.png
urlString = "http://127.0.0.1:8020/kindeditor-4.1.11-zh-CN/kindeditor/"+callBackPath+"?error=0&url="+"http://127.0.0.1:8081/static/1.png"; response.sendRedirect(urlString);
说到图片地址的url这里需要配置一下 我是用的一个配置类 ImgPathConf.java 位置放的不太规范 不过这不重要。。
ImgPathConf.java内容如下 是配置访问图片资源的 这里定义了访问项目目录下 和 不在项目目录下的两种方法
package com.example.upload.up; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @SuppressWarnings("deprecation") @Configuration public class ImgPathConf extends WebMvcConfigurerAdapter{ @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { //和页面有关的静态目录都放在项目的static目录下 registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/"); //上传的图片在D盘下的OTA目录下,访问路径如:http://localhost:8081/OTA/1.jpg //其中OTA表示访问的前缀。"file:D:/OTA/"是文件真实的存储路径 registry.addResourceHandler("/OTA/**").addResourceLocations("file:D:/OTA/"); } }
到这里 我们的项目已经可以跑起来了
效果如下 这里用到了Hbuilder 跑html还是挺方便的。
查看这个源码
可以看到图片是一个url地址 我们获取到textarea的内容 保存到数据库就OK了。
附加一个ajax提交内容的js 我的是upload.js
function upload(){ editor1.sync(); //将编辑器的内容设置到原来的textarea控件里。 var content=editor1.html(); url = "http://127.0.0.1:8081/upload/subContent"; $.post( url, { context1:content, }, function(retData) { }); }
至此一个完整的图片上传,内容提交就完成了 后台获取的内容打印如下 保存到数据库就OK了