springboot整合H+,基于summernote的富文本编辑器图片上传

我在做这块任务时遇到了好几个问题,也查了一些资料,自己总结的一些东西,希望可以帮到一些有需要的朋友,废话不多说开始看代码.
首先看前台页面:
需要注意的是summernote的默认图片上传是base64编码所以我么要重写上传方法,还有一个特别关键的问题,要过滤富文本里的内容,不然直接从word粘贴过来的内容无法保存,还有中间夹杂%也无法保存或保存数据或数据丢失的问题,</span>
<!DOCTYPE html>
<html>


<!-- Mirrored from www.zi-han.net/theme/hplus/form_editors.html by HTTrack Website Copier/3.x [XR&CO'2014], Wed, 20 Jan 2016 14:19:35 GMT -->
<head>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">


    <title>H+ 后台主题UI框架 - 富文本编辑器</title>
    <meta name="keywords" content="H+后台主题,后台bootstrap框架,会员中心主题,后台HTML,响应式后台">
    <meta name="description" content="H+是一个完全响应式,基于Bootstrap3最新版本开发的扁平化主题,她采用了主流的左右两栏式布局,使用了Html5+CSS3等现代技术">

    <link rel="shortcut icon" href="favicon.ico"> <link href="../hplus/css/bootstrap.min14ed.css?v=3.3.6" rel="stylesheet">
    <link href="../hplus/css/font-awesome.min93e3.css?v=4.4.0" rel="stylesheet">
    <link href="../hplus/css/animate.min.css" rel="stylesheet">
    <link href="../hplus/css/plugins/summernote/summernote.css" rel="stylesheet">
    <link href="../hplus/css/plugins/summernote/summernote-bs3.css" rel="stylesheet">
    <link href="../hplus/css/style.min862f.css?v=4.1.0" rel="stylesheet">

</head>

<body class="gray-bg">
<div class="wrapper wrapper-content">

    <div class="row">
        <div class="col-sm-12">
            <div class="ibox float-e-margins">

                <div class="ibox-title">
                    内容标题:&nbsp;&nbsp;<input id="title_text" type="text">&nbsp;*
                </div>

                <div class="ibox-content no-padding">
                    <button id="save" class="btn btn-primary  btn-xs" οnclick="save()" type="button">保存</button>
                    <button id="btn" class="btn btn-primary  btn-xs"  type="button" οnclick="preview()">预览</button>
                    <div class="summernote">


                    </div>

                </div>
            </div>
        </div>
    </div>
    <!--预览-->
    <div id="preview" style="display: none">
        <button class="btnfan" οnclick="hide()">返回</button>
        <div class="preview_box">
            <div class="preview_box_last" id="preview_box_last">

            </div>
        </div>
    </div>
    <div class="row">
        <div class="col-sm-12">
            <div class="ibox float-e-margins">


            </div>
        </div>
    </div>

</div>
<script src="../hplus/js/jquery.min.js?v=2.1.4"></script>
<script src="../hplus/js/bootstrap.min.js?v=3.3.6"></script>
<script src="../hplus/js/content.min.js?v=1.0.0"></script>
<script src="../hplus/js/plugins/summernote/summernote.min.js"></script>
<script src="../hplus/js/plugins/summernote/summernote-zh-CN.js"></script>


<script>
    window.onload=function(){

        getId()
    }
    var id=localStorage.getItem("id");
    console.log(id);
    var arr=[];
    $(document).ready(function(){
        $(".summernote").summernote({lang:"zh-CN",
            callbacks: {

                onImageUpload: function(files) {
                    // 上传图片到服务器并且插入图片到编辑框
                    //alert("aaa");

                    sendFile(files[0])
                },
                 onPaste: function(ne) {

                     var bufferText = ((ne.originalEvent || ne).clipboardData || window.clipboardData).getData('Text/plain');
                     //    ne.preventDefault();
                     ne.preventDefault ? ne.preventDefault() : (ne.returnValue = false);
                     // Firefox fix
                     setTimeout(function () {
                         document.execCommand("insertText", false, bufferText);
                     }, 10);
                 }
            }
        })
    })
    function getId(){


        if(id==''){

        }else{
            $.ajax({
                type:"get",
                url:'/content/service/byId?id='+id+'',
                cache:false,
                async:false, //是否异步
                success:function(data) {
                    console.log(typeof data);
                    document.getElementById("title_text").value=data.title;
                    console.log(data.title);
                    var markupStr = ''+data.content+'';
                    $('.summernote').summernote('code', markupStr);

                    localStorage.removeItem('id');

                },

            })
        }
    }
    ; var edit=function(){$("#eg").addClass("no-padding");
        $(".click2edit").summernote({lang:"zh-CN",focus:true})};
    function sendFile(file){

        var filename=false;

        filename=file['name'];
        filename=false;
        if(!filename){
            $(".note-alarm").remove();
        }
        data=new FormData();

        data.append("file",file);

        data.append("key",filename);
        console.log(file);

        $.ajax({

            data:data,
            type:"post",
            url:'/content/upload',
            cache:false,
            dataType:'json',
            contentType:false,
            processData:false,
            success:function (data) {
                // console.log(typeof data );
                data=JSON.parse(data)
                //console.log(typeof data );
                console.log(data.path);
                $('.summernote').summernote('editor.insertImage', data.path)
                arr.push(data.path);
            },
            error:function () {
                alert("上传失败");
            }
        })
    }
    function save() {

        //var aHTML=$(".summernote").code();
        //console.log(aHTML)
        var aa=$('.summernote').summernote('code')
        console.log(typeof aa)
        var title=document.getElementById("title_text").value;


        if(id==""||id==null||id=="null"){
            if(title==""){
                alert("请输入标题");

            }else{
                var str=''
                var _str=''
                str=''+aa+''
                //summernote会把空格以后或者带%的所有内容自动去掉,所以这里替换所有空格和转%

                var st= encodeURIComponent(str);
                $.ajax({
                    type:'post', //方式
                    url:'/content/service',
                    data:"content="+st+"&title="+title,
                    async:false,   //是否异步
                    success:function(data) {
                        alert("成功");
                        window.location.href="/content"
                    },
                    error:function () {
                        alert("上传失败");
                    }
                })
            }
        }else{
            if(title==""){
                alert("请输入标题");

            }else{

                var str=''
                var _str=''
                str=''+aa+''
                //summernote会把空格以后或者带%的所有内容自动去掉,所以这里替换所有空格和转%

                var st= encodeURIComponent(str);
                $.ajax({
                    type:'put', //方式
                    url:'/content/service',
                    data:"content="+st+"&title="+title+"&id="+id,

                    async:false,   //是否异步
                    success:function(data) {
                        alert("成功");
                        console.log(data);
                        window.location.href="/content"
                    },
                    error:function () {
                        //    console.log(id2);
                        alert("上传失败2");
                    }
                })
            }
        }


    }

    function preview(){
        var aa=$('.summernote').summernote('code');
        document.getElementById("preview_box_last").innerHTML=aa;

        document.getElementById('preview').style.display="block";

    };
    function hide() {
        document.getElementById('preview').style.display="none";
        document.getElementById("preview_box_last").innerHTML="";
    }


</script>

<script type="text/javascript" src="http://tajs.qq.com/stats?sId=9051096" charset="UTF-8"></script>
</body>


</html>

 这是页面效果:
下面是后台Controller代码,在后台有两个地方很重要,页很容易出错
/**
 * 
富文本图片上传保存
 
* 
@param 
request
 
* 
@return
 
*/
@RequestMapping(value = "/upload",
 method = RequestMethod.POST)
@ResponseBody
public 
String Content( HttpServletRequest request) {
//创建map集合
Map<String,Object> map=new HashMap<String,Object>();
try {
        // 转换成多部分request
    MultipartHttpServletRequest multipartRequest=((MultipartHttpServletRequest) request);
        //获得上传的所有文件名
        Iterator<String> fileNameIter = multipartRequest.getFileNames();
        //进行循环遍历
        while (fileNameIter.hasNext()){
            //根据文件名获取文件
            MultipartFile file =multipartRequest.getFile(fileNameIter.next());
            //若文件不为null
            if(file!=null){
                //获取上传时的文件名
                String  myFilename=file.getOriginalFilename();
                System.out.println("上传时的文件名:"+myFilename);
                //去除空格
                if(myFilename.trim()!=""){
                    //获得文件名
                    String filename=file.getOriginalFilename();
                    //截取文件名
                    String fileBaseName=filename.substring(0,filename.lastIndexOf("."));
                    //截取文件后缀
                    String fileExt=filename.substring(filename.lastIndexOf(".")+1).toLowerCase();
                    //时间格式化对象
                    SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyyMMddHHmmss");
                    //生成时间戳
                    String newFilename=simpleDateFormat.format(new Date());
                    //生成新的文件名
                    String filenames=newFilename+new Random().nextInt(1000)+"."+fileExt;
                    //获得保存文件路径
                    String filePath=request.getSession().getServletContext().
                            getRealPath("/")+"\\upload\\"+filenames;
                   //部署保存路径
                    //String filePath=imageHtmlLocation+filenames;
                    System.out.println("保存的路径:"+filePath);
                    //保存文件
                    File targetFile = new File(filePath);
                    if(!targetFile.exists()){
                        //先得到文件的上级目录,并创建上级目录,在创建文件
                        targetFile.getParentFile().mkdir();
                        try {
                            //创建文件
                            targetFile.createNewFile();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    //上传文件
                    file.transferTo(targetFile);
                    //获得工程的相对路径
                    String saveUrl ="http://127.0.0.1:8060/upload/"+filenames;
                    //部署访问路径
                    //String saveUrl =fileuploadPrefix+imageHtmlUrl+filenames;
                    System.out.println("相对路径:"+saveUrl);

                    //将文件保存的相对路径返回页面
                    map.put("path",saveUrl);
                }
            }
        }
    //保存添加信息
    request.setAttribute("msg", "true");
    return JSON.toJSONString(map);

} catch (Exception e) {
    e.printStackTrace();
    //保存失败
    request.setAttribute("msg", "false");
    return null;
}

总结一下:这样基本上就可以实现图片的保存了,因为基于springboot每次重新运行,tomcat的运行路径就会发生改变,所以当重新启动会发现前面存储的文件通过http访问不到了,所以最终部署要在 application.properties中进行映射配置,比如
 
 
#传图提问保存图片路径
question.image.location=G:/home/web/static/fileupload/image/question
question.image.url=/fileupload/image/question
  后台代码中进行引入就可以实现路径的映射</span>
 
 
 
//引入图片存储映射路径
@Value("${image.html.location}")
private String 
imageHtmlLocation;

//引入图片访问映射路径
@Value("${image.html.url}")
private String 
imageHtmlUrl;




实现富文本编辑器可以使用一些开源的JavaScript库,比如常用的有: 1. CKEditor:功能强大、可扩展性好、使用方便,支持多种浏览器和平台,但是需要付费使用高级功能。 2. TinyMCE:也是一个功能强大的富文本编辑器,开源免费,支持多种浏览器和平台,易于集成到应用中。 3. Summernote:一个基于Bootstrap的富文本编辑器,开源免费,支持多种浏览器和平台,并且具有一些独特的功能,如代码视图、图片上传等。 4. Froala Editor:一个功能强大、易于使用的富文本编辑器,支持多种浏览器和平台,但是需要付费使用高级功能。 以下是基于SpringBoot和Thymeleaf实现使用CKEditor富文本编辑器的步骤: 1. 引入CKEditor相关的JavaScript和CSS文件,可以从官网下载或者使用CDN方式引入: ```html <!-- 引入CSS --> <link rel="stylesheet" href="https://cdn.ckeditor.com/4.16.0/standard/ckeditor.css"> <!-- 引入JS --> <script src="https://cdn.ckeditor.com/4.16.0/standard/ckeditor.js"></script> ``` 2. 在Thymeleaf模板中使用CKEditor: ```html <!-- 定义富文本编辑器容器 --> <div id="editor"></div> <!-- 初始化CKEditor --> <script> CKEDITOR.replace('editor'); </script> ``` 3. 在后端Controller中获取富文本编辑器中的内容: ```java @PostMapping("/save") public String save(@RequestParam("content") String content) { // 处理富文本编辑器中的内容 return "success"; } ``` 以上就是基于SpringBoot和Thymeleaf实现使用CKEditor富文本编辑器的步骤,其他富文本编辑器的使用方法类似。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值