之前demo相关博客查看的,只有3.x多的版本才有这些图标显示出来。应该是某些属性是用的老的样式,新版的没研究先用这3.x版本的吧。
https://www.bootcdn.cn/font-awesome/
https://plugins.jquery.com/hotkeys/
需要引入css:
<link th:href="@{/css/bootstrap-combined.no-icons.min.css}" rel="stylesheet"/> <link th:href="@{/bootstrap-4.4.1-dist/css/bootstrap.min.css}" rel="stylesheet" type="text/css" /> <link th:href="@{/css/font-awesome.css}" rel="stylesheet"/> <link th:href="@{/css/index.css}" rel="stylesheet"/>
js:
<script th:src="@{/js/jquery-3.4.1.min.js}"></script> <!--键盘事件--> <script th:src="@{/js/jquery.hotkeys.js}"></script> <!--bootstrap.bundle.min.js此文件包含Popper.min.js,只是点击下拉框需要双击才行--> <!--<script th:src="@{/bootstrap-4.4.1-dist/js/bootstrap.bundle.min.js}"></script>--> <!--富文本编辑框点击文字样式,和大小,下拉框没反应是因为没引入popper.min.js的问题。--> <script th:src="@{/js/popper.min.js}"></script> <script th:src="@{/bootstrap-4.4.1-dist/js/bootstrap.min.js}"></script> <!--<script th:src="@{/js/bootstrap-wysiwyg.js}"></script>--> <script th:src="@{/js/bootstrap-wysiwyg-define.js}"></script>
整体demo页面html:
1 <!DOCTYPE html> 2 <html lang="en" xmlns:th=http://www.thymeleaf.org> 3 <head> 4 <Meta charset="UTF-8"> 5 <title>编辑新闻详情页面</title> 6 <link th:href="@{/css/bootstrap-combined.no-icons.min.css}" rel="stylesheet"/> 7 <link th:href="@{/bootstrap-4.4.1-dist/css/bootstrap.min.css}" rel="stylesheet" type="text/css" /> 8 <link th:href="@{/css/font-awesome.css}" rel="stylesheet"/> 9 <link th:href="@{/css/index.css}" rel="stylesheet"/> 10 <style> 11 12 .editor-container { /* 编辑器容器样式 */ 13 14 padding: 25px 20px 25px; 15 16 margin-bottom: 10px; 17 18 background-color: #eeeeee; 19 20 -webkit-border-radius: 6px; 21 22 -moz-border-radius: 6px; 23 24 border-radius: 6px; 25 26 } 27 28 29 30 .btn-toolbar { 31 32 font-size: 0; 33 34 margin-top: 10px; 35 36 margin-bottom: 10px; 37 38 } 39 40 41 42 #editor { /* 编辑框样式 */ 43 44 max-height: 400px; 45 46 height: 400px; 47 48 width: 100%; 49 50 background-color: white; 51 52 border-collapse: separate; 53 54 border: 1px solid rgb(204, 204, 204); 55 56 padding: 4px; 57 58 Box-sizing: content-Box; 59 60 -webkit-Box-shadow: rgba(0, 0, 0, 0.0745098) 0px 1px 1px 0px inset; 61 62 Box-shadow: rgba(0, 0, 0, 0.0745098) 0px 1px 1px 0px inset; 63 64 border-top-right-radius: 3px; 65 66 border-bottom-right-radius: 3px; 67 68 border-bottom-left-radius: 3px; 69 70 border-top-left-radius: 3px; 71 72 overflow: scroll; 73 74 outline: none; 75 76 } 77 78 79 80 /* 工具条里按钮样式,这个样式其实是.btn-default的样式, 81 82 Button按钮之所以没有直接加上.btn-default样式是因为按钮选中后wysiwyg会给选中的按钮加.btn-info样式, 83 84 .btn-default和.btn-info同时存在样式会冲突 */ 85 .btn-toolbar .btn { 86 87 88 color: #333; 89 90 background-color: #fff; 91 92 border-color: #ccc; 93 94 } 95 96 97 98 /* 这个样式其实是.btn-info的样式,重写一遍是为了提高优先级, 99 100 否则.btn-info的样式会被.btn-toolbar .btn覆盖,这个样式要写在.btn-toolbar .btn之下 */ 101 .btn-toolbar .btn-info { 102 103 color: #fff; 104 105 background-color: #5bc0de; 106 107 border-color: #46b8da; 108 109 } 110 111 </style> 112 </head> 113 <body> 114 <div class="btn-toolbar" data-role="editor-toolbar" data-target="#editor"> 115 <div class="btn-group"> 116 <a class="btn dropdown-toggle" data-toggle="dropdown" title="Font"><i class="icon-font"></i><b class="caret"></b></a> 117 <ul class="dropdown-menu"> </ul> 118 </div> 119 <div class="btn-group"> 120 <a class="btn dropdown-toggle" data-toggle="dropdown" title="Font Size"><i class="icon-text-height"></i> <b class="caret"></b></a> 121 <ul class="dropdown-menu"> 122 <li><a data-edit="fontSize 5"><font size="5">Huge</font></a></li> 123 <li><a data-edit="fontSize 3"><font size="3">normal</font></a></li> 124 <li><a data-edit="fontSize 1"><font size="1">Small</font></a></li> 125 </ul> 126 </div> 127 <div class="btn-group"> 128 <a class="btn" data-edit="bold" title="Bold (Ctrl/Cmd+B)"><i class="icon-bold"></i></a> <!--加粗--> 129 <a class="btn" data-edit="italic" title="Italic (Ctrl/Cmd+I)"><i class="icon-italic"></i></a><!-- 斜体--> 130 <a class="btn" data-edit="strikethrough" title="Strikethrough"><i class="icon-strikethrough"></i></a><!-- 删除线--> 131 <a class="btn" data-edit="underline" title="Underline (Ctrl/Cmd+U)"><i class="icon-underline"></i></a><!-- 下划线--> 132 </div> 133 <div class="btn-group"> 134 <a class="btn" data-edit="insertunorderedlist" title="Bullet list"><i class="icon-list-ul"></i></a><!-- 加点--> 135 <a class="btn" data-edit="insertorderedlist" title="Number list"><i class="icon-list-ol"></i></a><!-- 数字排序--> 136 <a class="btn" data-edit="outdent" title="Reduce indent (Shift+Tab)"><i class="icon-indent-left"></i></a><!-- 减少缩进--> 137 <a class="btn" data-edit="indent" title="Indent (Tab)"><i class="icon-indent-right"></i></a><!--增加缩进--> 138 </div> 139 <div class="btn-group"> 140 <a class="btn" data-edit="justifyleft" title="Align Left (Ctrl/Cmd+L)"><i class="icon-align-left"></i></a><!--左对齐--> 141 <a class="btn" data-edit="justifycenter" title="Center (Ctrl/Cmd+E)"><i class="icon-align-center"></i></a><!-- 居中 --> 142 <a class="btn" data-edit="justifyright" title="Align Right (Ctrl/Cmd+R)"><i class="icon-align-right"></i></a><!--右对齐--> 143 <a class="btn" data-edit="justifyfull" title="Justify (Ctrl/Cmd+J)"><i class="icon-align-justify"></i></a><!--垂直对齐--> 144 </div> 145 <div class="btn-group"> 146 <a class="btn dropdown-toggle" data-toggle="dropdown" title="Hyperlink"><i class="icon-link"></i></a><!-- 链接--> 147 <div class="dropdown-menu input-append"> 148 <input class="span2" placeholder="URL" type="text" data-edit="createLink"/> 149 <button class="btn" type="button">Add</button> 150 </div> 151 <a class="btn" data-edit="unlink" title="Remove Hyperlink"><i class="icon-cut"></i></a> 152 </div> 153 <div class="btn-group"> 154 <a class="btn" title="Insert picture (or just drag & drop)" id="pictureBtn"><i class="icon-picture"></i></a> 155 <input type="file" id="pictureInput" name="picture" data-role="magic-overlay" data-target="#pictureBtn" data-edit="insertimage" action="/ylxtWeb/news/upload"/> 156 </div> 157 <div class="btn-group"> 158 <a class="btn" data-edit="undo" title="Undo (Ctrl/Cmd+Z)"><i class="icon-undo"></i></a><!--撤销--> 159 <a class="btn" data-edit="redo" title="Redo (Ctrl/Cmd+Y)"><i class="icon-repeat"></i></a><!--恢复--> 160 </div> 161 <input type="text" data-edit="inserttext" id="voiceBtn" x-webkit-speech=""> 162 </div> 163 164 <div id="editor" contenteditable="true" th:text="${news?.content}"></div> 165 <div style="text-align: center;margin-top: 10px;"> 166 <button class="btn-info" onclick="cancel()" >返回</button> 167 <button class="btn-info" onclick="clea()" style="margin: 0 36px;">清空</button> 168 <button class="btn-info" id="confirmBtn" onclick="confir()" th:attr="news_id=${news?.id}" >确定</button> 169 </div> 170 <form action="" id="myForm" style="display: none;"> 171 <input type="text" name="news" th:value="${news}"> 172 </form> 173 </body> 174 <script th:src="@{/js/jquery-3.4.1.min.js}"></script> 175 <!--键盘事件--> 176 <script th:src="@{/js/jquery.hotkeys.js}"></script> 177 <!--bootstrap.bundle.min.js此文件包含Popper.min.js,只是点击下拉框需要双击才行--> 178 <!--<script th:src="@{/bootstrap-4.4.1-dist/js/bootstrap.bundle.min.js}"></script>--> 179 <!--富文本编辑框点击文字样式,和大小,下拉框没反应是因为没引入popper.min.js的问题。--> 180 <script th:src="@{/js/popper.min.js}"></script> 181 <script th:src="@{/bootstrap-4.4.1-dist/js/bootstrap.min.js}"></script> 182 <!--<script th:src="@{/js/bootstrap-wysiwyg.js}"></script>--> 183 <script th:src="@{/js/bootstrap-wysiwyg-define.js}"></script> 184 185 <script th:inline="javascript"> 186 function cancel(){ 187 window.location.href = baseUrl+"/news/toPageNews"; 188 } 189 function clea(){ 190 console.log(222); 191 //获取清除HTML标签后的内容: 192 $("#editor").empty(); 193 } 194 195 function confir(){ 196 //获取富文本编辑器的内容,和获取普通div内容一样。 197 var cont = $("#editor").html(); 198 console.log(cont); 199 200 var news_id = $("#confirmBtn").attr("news_id"); 201 var data_news=[[${news}]] 202 data_news.content = cont; 203 var formEle = document.getElementById("myForm"); 204 formEle.action = baseUrl+"/news/updateNews"; 205 var formData = new FormData(formEle); 206 /*Object.keys(data_news).forEach((key) => { 207 formData.append(key, data_news[key]); 208 }); 209 console.log(formData.get("title")+"5555"+formData.get("isDelete"));*/ 210 //formEle.submit(); 211 //提交表单 212 var xhr = new XMLHttpRequest(); 213 xhr.open('PUT', baseUrl+"/news", true); 214 xhr.onload = function () { 215 if (xhr.status !== 200) { 216 console.log('An error occurred!'); 217 } 218 }; 219 xhr.send(formData); 220 } 221 var baseUrl = ""; 222 $(function(){ 223 var pathName = window.location.pathname.substring(1); 224 var webName = pathName == '' ? '' : pathName.substring(0, pathName.indexOf('/')); 225 baseUrl = window.location.protocol + '//' + window.location.host+'/' + webName + '/'; 226 // 初始化工具条 227 initToolbarBootstrapBindings(); 228 $('#editor').wysiwyg(); 229 }); 230 231 // 初始化工具条 232 function initToolbarBootstrapBindings() { 233 // 字体样式 234 var fonts = [ 'Serif', 'Sans', 'Arial', 'Arial Black', 'Courier', 235 'Courier New', 'Comic Sans MS', 'Helvetica', 'Impact', 236 'Lucida Grande', 'Lucida Sans', 'Tahoma', 'Times', 237 'Times New Roman', 'Verdana' ], 238 fontTarget = $('[title=Font]').siblings('.dropdown-menu'); 239 $.each(fonts,function(idx, fontName) { 240 fontTarget.append($('<li><a href="#" data-edit="fontName ' + fontName 241 +'" style="font-family:\''+ fontName +'\'">' + fontName + '</a></li>')); 242 }); 243 244 $('button[title]').tooltip({ 245 container : 'body' 246 }); 247 248 // .dropdown-menu下的input事件 249 $('.dropdown-menu input').click(function() { 250 return false; 251 }) 252 .change(function() { 253 $(this).parent('.dropdown-menu').siblings('.dropdown-toggle').dropdown('toggle'); 254 }) 255 .keydown('esc', function() { 256 this.value = ''; 257 $(this).change(); 258 }); 259 260 // [data-role=magic-overlay]的样式 261 $('[data-role=magic-overlay]').each(function() { 262 var overlay = $(this), target = $(overlay.data('target')); 263 overlay.css('opacity', 0).css('position', 'absolute') 264 .offset(target.offset()).width(target.outerWidth()) 265 .height(target.outerHeight()); 266 }); 267 }; 268 269 </script> 270 </html>View Code
查了好多博客里边的demo的图片都是没有上传到服务器的,需要修改bootstrap-wysiwyg.js文件,原理为:选中图片后就上传到服务器,然后服务端返回图片访问链接,前端把链接写入img标签的src属性内,并放到编辑框内,
修改后的bootstrap-wysiwyg.js文件,更名为bootstrap-wysiwyg-define.js引入了thymeleaf模板页面。
/* http://github.com/mindmup/bootstrap-wysiwyg */ /*global jQuery, $, FileReader*/ /*jslint browser:true*/ (function ($) { 'use strict'; /*转码图片*/ var readFileIntoDataUrl = function (fileInfo) { var loader = $.Deferred(), //jq延迟对象 fReader = new FileReader(); fReader.onload = function (e) { loader.resolve(e.target.result); }; fReader.onerror = loader.reject; //拒绝 fReader.onprogress = loader.notify; fReader.readAsDataURL(fileInfo); //转码图片 return loader.promise(); //返回promise对象,观察某种类型被绑定到集合的所有行动,是否已被加入到队列中。 }; //一、修改原readFileIntoDataUrl方法 /*var readFileIntoDataUrl = function (fileInfo) { var loader = $.Deferred(), fReader = new FileReader(), img = ''; fReader.onload = function (e) { img = e.target.result; $.ajax({ url: ctxPath+'news/upload', type: 'post', async: false, dataType: 'json', data: {"file":fileInfo}, success: function(data){ if(data.responseCode == 1){ loader.resolve(服务器返回的图片的地址); }else if(data.responseCode == 0){ alert('上传失败'); } } }); }; fReader.onerror = loader.reject; fReader.onprogress = loader.notify; fReader.readAsDataURL(fileInfo); return loader.promise(); };*/ var uploadFiletoServer = function(id, action, callback) { var fileObj = document.getElementById("pictureInput").files[0]; // js 获取文件对象 var tokenv="ssssssss"; //var data = {"id":id,"picture":fileObj}; var formData = new FormData();//document.getElementById("myForm") //formData.append("picture",$("#pictureInput")[0].files[0]); formData.append("file",fileObj); formData.append("token",tokenv); console.log(formData); $.ajax({ type: 'post', url : action, cache: false, data: formData, processData: false,//如果processData不設置為false,jquery會把formData轉換為字符串。 contentType : false,//不设置是:application/x-www-form-urlencoded; dataType : 'json', success : function(obj) { if (obj.status) { callback(obj.imgsrc); } else options.fileUploadError("server-internal-exception", obj.message); }, error : function(e) { console.log(e); //options.fileUploadErroe("upload-failure", ""); } });} /*清空内容*/ $.fn.cleanHtml = function () { var html = $(this).html(); return html && html.replace(/(<br>|\s|<div><br><\/div>| )*$/, ''); }; $.fn.wysiwyg = function (userOptions) { var editor = this, //设置ui-jq='设置的插件别名的dom元素'(此句注释可忽略,是针对我的项目结构写的) selectedRange, options, toolbarBtnSelector, //更新工具栏 updatetoolbar = function () { if (options.activetoolbarClass) { $(options.toolbarSelector).find(toolbarBtnSelector).each(function () { var command = $(this).data(options.commandRole); //判断光标所在位置以确定命令的状态,为真则显示为激活 if (document.queryCommandState(command)) { $(this).addClass(options.activetoolbarClass); } else { $(this).removeClass(options.activetoolbarClass); } }); } }, //插入内容 execCommand = function (commandWithArgs, valueArg) { var commandArr = commandWithArgs.split(' '), command = commandArr.shift(), args = commandArr.join(' ') + (valueArg || ''); document.execCommand(command, 0, args); updatetoolbar(); }, //用jquery.hotkeys.js插件监听键盘 bindHotkeys = function (hotKeys) { $.each(hotKeys, function (hotkey, command) { editor.keydown(hotkey, function (e) { if (editor.attr('contenteditable') && editor.is(':visible')) { e.preventDefault(); e.stopPropagation(); execCommand(command); } }).keyup(hotkey, function (e) { if (editor.attr('contenteditable') && editor.is(':visible')) { e.preventDefault(); e.stopPropagation(); } }); }); }, //获取当前range对象 getCurrentRange = function () { var sel = window.getSelection(); if (sel.getRangeAt && sel.rangeCount) { return sel.getRangeAt(0); //从当前selection对象中获得一个range对象。 } }, //保存 saveSelection = function () { selectedRange = getCurrentRange(); }, //恢复 restoreSelection = function () { var selection = window.getSelection(); //获取当前既获区,selection是对当前激活选中区(即高亮文本)进行操作 if (selectedRange) { try { //移除selection中所有的range对象,执行后anchorNode、focusNode被设置为null,不存在任何被选中的内容。 selection.removeAllRanges(); } catch (ex) { document.body.createTextRange().select(); document.selection.empty(); } //将range添加到selection当中,所以一个selection中可以有多个range。 //注意Chrome不允许同时存在多个range,它的处理方式和Firefox有些不同。 selection.addRange(selectedRange); } }, //插入文件(这里指图片) //将insertFiles方法作改写如下: insertFiles = function (files, id, action) { editor.focus(); //遍历插入(应为可以多文件插入) $.each(files, function (idx, fileInfo) { //只可插入图片文件 if (/^image\//.test(fileInfo.type)) { //转码图片 /* * $.when(readFileIntoDataUrl(fileInfo)).done(function(dataUrl) { * execCommand('insertimage', dataUrl); }).fail(function(e) { * options.fileUploadError("file-reader", e); }); */ uploadFiletoServer(id, action, function(src) { execCommand('insertimage', src); }); } else { //非图片文件会调用config的错误函数 options.fileUploadError("unsupported-file-type", fileInfo.type); } }); }, //Todo 暂不了解用意 markSelection = function (input, color) { restoreSelection(); //确定命令是否被支持,返回true或false if (document.queryCommandSupported('hiliteColor')) { document.execCommand('hiliteColor', 0, color || 'transparent'); } saveSelection(); input.data(options.selectionMarker, color); }, //绑定工具栏相应工具事件 bindToolbar = function (toolbar, options) { //给所有工具栏上的控件绑定点击事件 toolbar.find(toolbarBtnSelector).click(function () { restoreSelection(); editor.focus(); //获取焦点 //设置相应配置的工具execCommand execCommand($(this).data(options.commandRole)); //保存 saveSelection(); }); //对[data-toggle=dropdown]进行单独绑定点击事件处理 字体大小 toolbar.find('[data-toggle=dropdown]').click(restoreSelection); //对input控件进行单独处理,webkitspeechchange为语音事件 toolbar.find('input[type=text][data-' + options.commandRole + ']').on('webkitspeechchange change', function () { var newValue = this.value; //获取input 的value this.value = ''; //清空value防止冲突 restoreSelection(); if (newValue) { editor.focus();//获取焦点 //设置相应配置的工具execCommand execCommand($(this).data(options.commandRole), newValue); } saveSelection(); }).on('focus', function () { //获取焦点 var input = $(this); if (!input.data(options.selectionMarker)) { markSelection(input, options.selectionColor); input.focus(); } }).on('blur', function () { //失去焦点 var input = $(this); if (input.data(options.selectionMarker)) { markSelection(input, false); } }); //图片按钮添加了监听器事件 toolbar.find('input[type=file][data-' + options.commandRole + ']') .change( function() { restoreSelection(); if (this.type === 'file' && this.files && this.files.length > 0) { insertFiles(this.files, $(this).attr('id'), $(this).attr('action')); } saveSelection(); this.value = ''; }); }, //初始化拖放事件 initFileDrops = function () { editor.on('dragenter dragover', false) .on('drop', function (e) { var dataTransfer = e.originalEvent.dataTransfer; e.stopPropagation(); e.preventDefault(); if (dataTransfer && dataTransfer.files && dataTransfer.files.length > 0) { insertFiles(dataTransfer.files); } }); }; //合并传入的配置对象userOptions和默认的配置对象config options = $.extend({}, $.fn.wysiwyg.defaults, userOptions); //设置查找字符串:a[data-edit] button[data-edit] input[type=button][data-edit] toolbarBtnSelector = 'a[data-' + options.commandRole + '],button[data-' + options.commandRole + '],input[type=button][data-' + options.commandRole + ']'; //设置热键 容器有[data-role=editor-toolbar]属性的dom元素 bindHotkeys(options.hotKeys); //是否允许拖放 允许则配置拖放 if (options.dragAndDropImages) {initFileDrops();} //配置工具栏 bindToolbar($(options.toolbarSelector), options); //设置编辑区域为可编辑状态并绑定事件mouseup keyup mouSEOut editor.attr('contenteditable', true) .on('mouseup keyup mouSEOut', function () { saveSelection(); updatetoolbar(); }); //编辑区域绑定图片点击事件 //Todo 这是我自己添加的,因为有时要对图片进行一些操作 editor.on('mousedown','img', function (e) { e.preventDefault(); }).on('click', 'img', function (e) { var $img = $(e.currentTarget); console.log($img); e.preventDefault(); e.stopPropagation(); }); //window绑定touchend事件 $(window).bind('touchend', function (e) { var isInside = (editor.is(e.target) || editor.has(e.target).length > 0), currentRange = getCurrentRange(), clear = currentRange && (currentRange.startContainer === currentRange.endContainer && currentRange.startOffset === currentRange.endOffset); if (!clear || isInside) { saveSelection(); updatetoolbar(); } }); return this; }; //配置参数 $.fn.wysiwyg.defaults = { hotKeys: { //热键 应用hotkeys.js jquery插件 'ctrl+b Meta+b': 'bold', 'ctrl+i Meta+i': 'italic', 'ctrl+u Meta+u': 'underline', 'ctrl+z Meta+z': 'undo', 'ctrl+y Meta+y Meta+shift+z': 'redo', 'ctrl+l Meta+l': 'justifyleft', 'ctrl+r Meta+r': 'justifyright', 'ctrl+e Meta+e': 'justifycenter', 'ctrl+j Meta+j': 'justifyfull', 'shift+tab': 'outdent', 'tab': 'indent' }, toolbarSelector: '[data-role=editor-toolbar]', commandRole: 'edit', activetoolbarClass: 'btn-info', selectionMarker: 'edit-focus-marker', selectionColor: 'darkgrey', dragAndDropImages: true, //是否支持拖放,默认为支持 fileUploadError: function (reason, detail) { console.log("File upload error", reason, detail); } }; }(window.jQuery));
/** * * @param file multipartfile 这个类一般是用来接受前台传过来的文件 * @param request * @return */ @ResponseBody @RequestMapping(value = "/upload",method = RequestMethod.POST) public Map<String,Object> multiUpload(@RequestParam("file") multipartfile file, HttpServletRequest request) { Map<String,Object> res = new HashMap<String, Object>(); try { String scheme = request.getScheme();//http String serverName = request.getServerName();//localhost int serverPort = request.getServerPort();//8080 String contextpath = request.getcontextpath();//项目名 String url = scheme+"://"+serverName+":"+serverPort+contextpath;//http://127.0.0.1:8080/test LOGGER.info("url:"+url); String imgurl = ""; //String imgurl=imgPath.substring(0,imgPath.length()-2);//截取到的是"/static/",如果配置访问路径的话 String path = request.getcontextpath(); String intactPath =null; String filename=file.getoriginalFilename(); String imgDir = imgServerPath.substring(imgServerPath.indexOf("file:") + 5, imgServerPath.length()); File file2 = new File(imgDir, filename); LOGGER.info("imgDir:"+imgDir); //得到原始文件的输入流 InputStream inputStream=file.getInputStream(); FileOutputStream fileOutputStream=new FileOutputStream(file2); //写出文件 IoUtils.copy(inputStream,fileOutputStream); inputStream.close(); fileOutputStream.close(); if(!file.isEmpty()){ imgurl = url+File.separator + file.getoriginalFilename(); System.out.println(intactPath); int pre = (int) System.currentTimeMillis(); } res.put("status","succ"); res.put("imgsrc",imgurl); } catch (Exception e) { res.put("status","error"); res.put("msg",e.getMessage()); e.printstacktrace(); LOGGER.info("multiUpload方法异常!",e); System.out.println(e.getMessage()); } return res; }
参考链接: