首页 > 技术文章 > springboot 使用kindeditor 页面跨域 图片上传 图片获取 前后分离

huobi 2018-10-15 19:43 原文

今天使用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了

 

推荐阅读