我在做这块任务时遇到了好几个问题,也查了一些资料,自己总结的一些东西,希望可以帮到一些有需要的朋友,废话不多说开始看代码.
首先看前台页面:
需要注意的是summernote的默认图片上传是base64编码所以我么要重写上传方法,还有一个特别关键的问题,要过滤富文本里的内容,不然直接从word粘贴过来的内容无法保存,还有中间夹杂%也无法保存或保存数据或数据丢失的问题,</span>
<!DOCTYPE html><html><!-- Mirrored from www.zi-/theme/hplus/form_editors.html by HTTrack Website Copier/3.x [XR&CO'], Wed, 20 Jan 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">内容标题: <input id="title_text" type="text"> *</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="/stats?sId=9051096" charset="UTF-8"></script></body></html>
这是页面效果:
下面是后台Controller代码,在后台有两个地方很重要,页很容易出错
/** * 富文本图片上传保存 * @param request * @return */@RequestMapping(value = "/upload",method = RequestMethod.POST)@ResponseBodypublic 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/questionquestion.image.url=/fileupload/image/question
后台代码中进行引入就可以实现路径的映射</span>
//引入图片存储映射路径@Value("${image.html.location}")private String imageHtmlLocation;//引入图片访问映射路径@Value("${image.html.url}")private String imageHtmlUrl;
如果觉得《springboot整合H+ 基于summernote的富文本编辑器图片上传》对你有帮助,请点赞、收藏,并留下你的观点哦!