SpringMvc + Jsp+ 富文本 kindeditor 进行 图片ftp上传nginx服务器 实现
Posted ✧*꧁一品堂.技术学习笔记꧂*✧.
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringMvc + Jsp+ 富文本 kindeditor 进行 图片ftp上传nginx服务器 实现相关的知识,希望对你有一定的参考价值。
一:html 原生态的附件上传
二:实现逻辑分析;
1.1.1 需求分析
Common.js
1、绑定事件
2、初始化参数
3、上传图片的url:
/pic/upload
4、上图片参数名称:
uploadFile
5、返回结果数据类型json
参考文档:
http://kindeditor.net/docs/upload.html
返回格式(JSON)
1 //成功时 2 3 { 4 5 "error" : 0, 6 7 "url" : "http://www.example.com/path/to/file.ext" 8 9 } 10 11 //失败时 12 13 { 14 15 "error" : 1, 16 17 "message" : "错误信息" 18 19 } 20
6 Service
7: Controller
8:需要引入的jar包的maven 配置参数:
1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 2 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 3 4 <artifactId>taotao-common</artifactId> 5 <!-- jar包依赖 --> 6 <dependencies> 7 <!-- 时间操作组件 --> 8 <dependency> 9 <groupId>joda-time</groupId> 10 <artifactId>joda-time</artifactId> 11 </dependency> 12 <!-- Apache工具组件 --> 13 14 <dependency> 15 <groupId>org.apache.commons</groupId> 16 <artifactId>commons-io</artifactId> 17 </dependency> 18 <dependency> 19 <groupId>commons-net</groupId> 20 <artifactId>commons-net</artifactId> 21 </dependency> 22 <!-- Jackson Json处理工具包 --> 23 <dependency> 24 <groupId>com.fasterxml.jackson.core</groupId> 25 <artifactId>jackson-databind</artifactId> 26 </dependency> 27 <!-- 文件上传组件 --> 28 <dependency> 29 <groupId>commons-fileupload</groupId> 30 <artifactId>commons-fileupload</artifactId> 31 </dependency> 32 33 </dependencies> 34 35 36 </project>
三:逻辑实现:
1:前端实现:
1 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> 2 <link href="/js/kindeditor-4.1.10/themes/default/default.css" type="text/css" rel="stylesheet"> 3 <script type="text/javascript" charset="utf-8" src="/js/kindeditor-4.1.10/kindeditor-all-min.js"></script> 4 <script type="text/javascript" charset="utf-8" src="/js/kindeditor-4.1.10/lang/zh_CN.js"></script> 5 <div style="padding:10px 10px 10px 10px"> 6 <form id="itemAddForm" class="itemForm" method="post"> 7 <table cellpadding="5"> 8 <tr> 9 <td>商品类目:</td> 10 <td> 11 <a href="javascript:void(0)" class="easyui-linkbutton selectItemCat">选择类目</a> 12 <input type="hidden" name="cid" style="width: 280px;"></input> 13 </td> 14 </tr> 15 <tr> 16 <td>商品标题:</td> 17 <td><input class="easyui-textbox" type="text" name="title" data-options="required:true" style="width: 280px;"></input></td> 18 </tr> 19 <tr> 20 <td>商品卖点:</td> 21 <td><input class="easyui-textbox" name="sellPoint" data-options="multiline:true,validType:\'length[0,150]\'" style="height:60px;width: 280px;"></input></td> 22 </tr> 23 <tr> 24 <td>商品价格:</td> 25 <td><input class="easyui-numberbox" type="text" name="priceView" data-options="min:1,max:99999999,precision:2,required:true" /> 26 <input type="hidden" name="price"/> 27 </td> 28 </tr> 29 <tr> 30 <td>库存数量:</td> 31 <td><input class="easyui-numberbox" type="text" name="num" data-options="min:1,max:99999999,precision:0,required:true" /></td> 32 </tr> 33 <tr> 34 <td>条形码:</td> 35 <td> 36 <input class="easyui-textbox" type="text" name="barcode" data-options="validType:\'length[1,30]\'" /> 37 </td> 38 </tr> 39 <tr> 40 <td>商品图片:</td> 41 <td> 42 <a href="javascript:void(0)" class="easyui-linkbutton picFileUpload">上传图片</a> 43 <input type="hidden" name="image"/> 44 </td> 45 </tr> 46 <tr> 47 <td>商品描述:</td> 48 <td> 49 <textarea style="width:800px;height:300px;visibility:hidden;" name="desc"></textarea> 50 </td> 51 </tr> 52 <tr class="params hide"> 53 <td>商品规格:</td> 54 <td> 55 56 </td> 57 </tr> 58 </table> 59 <input type="hidden" name="itemParams"/> 60 </form> 61 <div style="padding:5px"> 62 <a href="javascript:void(0)" class="easyui-linkbutton" onclick="submitForm()">提交</a> 63 <a href="javascript:void(0)" class="easyui-linkbutton" onclick="clearForm()">重置</a> 64 </div> 65 </div> 66 <script type="text/javascript"> 67 var itemAddEditor ; 68 //页面初始化完毕后执行此方法 69 $(function(){ 70 //创建富文本编辑器 71 itemAddEditor = TAOTAO.createEditor("#itemAddForm [name=desc]"); 72 //初始化类目选择和图片上传器 73 TAOTAO.init({fun:function(node){ 74 //根据商品的分类id取商品 的规格模板,生成规格信息。第四天内容。 75 //TAOTAO.changeItemParam(node, "itemAddForm"); 76 }}); 77 }); 78 //提交表单 79 function submitForm(){ 80 //有效性验证 81 if(!$(\'#itemAddForm\').form(\'validate\')){ 82 $.messager.alert(\'提示\',\'表单还未填写完成!\'); 83 return ; 84 } 85 //取商品价格,单位为“分” 86 $("#itemAddForm [name=price]").val(eval($("#itemAddForm [name=priceView]").val()) * 100); 87 //同步文本框中的商品描述 88 itemAddEditor.sync(); 89 //取商品的规格 90 /* 91 var paramJson = []; 92 $("#itemAddForm .params li").each(function(i,e){ 93 var trs = $(e).find("tr"); 94 var group = trs.eq(0).text(); 95 var ps = []; 96 for(var i = 1;i<trs.length;i++){ 97 var tr = trs.eq(i); 98 ps.push({ 99 "k" : $.trim(tr.find("td").eq(0).find("span").text()), 100 "v" : $.trim(tr.find("input").val()) 101 }); 102 } 103 paramJson.push({ 104 "group" : group, 105 "params": ps 106 }); 107 }); 108 //把json对象转换成字符串 109 paramJson = JSON.stringify(paramJson); 110 $("#itemAddForm [name=itemParams]").val(paramJson); 111 */ 112 //ajax的post方式提交表单 113 //$("#itemAddForm").serialize()将表单序列号为key-value形式的字符串 114 $.post("/item/save",$("#itemAddForm").serialize(), function(data){ 115 if(data.status == 200){ 116 $.messager.alert(\'提示\',\'新增商品成功!\'); 117 } 118 }); 119 } 120 121 function clearForm(){ 122 $(\'#itemAddForm\').form(\'reset\'); 123 itemAddEditor.html(\'\'); 124 } 125 </script> 126
commom.js
1 Date.prototype.format = function(format){ 2 var o = { 3 "M+" : this.getMonth()+1, //month 4 "d+" : this.getDate(), //day 5 "h+" : this.getHours(), //hour 6 "m+" : this.getMinutes(), //minute 7 "s+" : this.getSeconds(), //second 8 "q+" : Math.floor((this.getMonth()+3)/3), //quarter 9 "S" : this.getMilliseconds() //millisecond 10 }; 11 if(/(y+)/.test(format)){ 12 format = format.replace(RegExp.$1, (this.getFullYear()+"").substr(4 - RegExp.$1.length)); 13 } 14 for(var k in o) { 15 if(new RegExp("("+ k +")").test(format)){ 16 format = format.replace(RegExp.$1, RegExp.$1.length==1 ? o[k] : ("00"+ o[k]).substr((""+ o[k]).length)); 17 } 18 } 19 return format; 20 }; 21 22 var TT = TAOTAO = { 23 // 编辑器参数 24 kingEditorParams : { 25 //指定上传文件参数名称 26 filePostName : "uploadFile", 27 //指定上传文件请求的url。 28 uploadJson : \'/pic/upload\', 29 //上传类型,分别为image、flash、media、file 30 dir : "image" 31 }, 32 // 格式化时间 33 formatDateTime : function(val,row){ 34 var now = new Date(val); 35 return now.format("yyyy-MM-dd hh:mm:ss"); 36 }, 37 // 格式化连接 38 formatUrl : function(val,row){ 39 if(val){ 40 return "<a href=\'"+val+"\' target=\'_blank\'>查看</a>"; 41 } 42 return ""; 43 }, 44 // 格式化价格 45 formatPrice : function(val,row){ 46 return (val/1000).toFixed(2); 47 }, 48 // 格式化商品的状态 49 formatItemStatus : function formatStatus(val,row){ 50 if (val == 1){ 51 return \'正常\'; 52 } else if(val == 2){ 53 return \'<span style="color:red;">下架</span>\'; 54 } else { 55 return \'未知\'; 56 } 57 }, 58 59 init : function(data){ 60 // 初始化图片上传组件 61 this.initPicUpload(data); 62 // 初始化选择类目组件 63 this.initItemCat(data); 64 }, 65 // 初始化图片上传组件 66 initPicUpload : function(data){ 67 $(".picFileUpload").each(function(i,e){ 68 var _ele = $(e); 69 _ele.siblings("div.pics").remove(); 70 _ele.after(\'\\ 71 <div class="pics">\\ 72 <ul></ul>\\ 73 </div>\'); 74 // 回显图片 75 if(data && data.pics){ 76 var imgs = data.pics.split(","); 77 for(var i in imgs){ 78 if($.trim(imgs[i]).length > 0){ 79 _ele.siblings(".pics").find("ul").append("<li><a href=\'"+imgs[i]+"\' target=\'_blank\'><img src=\'"+imgs[i]+"\' width=\'80\' height=\'50\' /></a></li>"); 80 } 81 } 82 } 83 //给“上传图片按钮”绑定click事件 84 $(e).click(function(){ 85 var form = $(this).parentsUntil("form").parent("form"); 86 //打开图片上传窗口 87 KindEditor.editor(TT.kingEditorParams).loadPlugin(\'multiimage\',function(){ 88 var editor = this; 89 editor.plugin.multiImageDialog({ 90 clickFn : function(urlList) { 91 var imgArray = []; 92 KindEditor.each(urlList, function(i, data) { 93 imgArray.push(data.url); 94 form.find(".pics ul").append("<li><a href=\'"+data.url+"\' target=\'_blank\'><img src=\'"+data.url+"\' width=\'80\' height=\'50\' /></a></li>"); 95 }); 96 form.find("[name=image]").val(imgArray.join(",")); 97 editor.hideDialog(); 98 } 99 }); 100 }); 101 }); 102 }); 103 }, 104 105 // 初始化选择类目组件 106 initItemCat : function(data){ 107 $(".selectItemCat").each(function(i,e){ 108 var _ele = $(e); 109 if(data && data.cid){ 110 _ele.after("<span style=\'margin-left:10px;\'>"+data.cid+"</span>"); 111 }else{ 112 _ele.after("<span style=\'margin-left:10px;\'></span>"); 113 } 114 _ele.unbind(\'click\').click(function(){ 115 $("<div>").css({padding:"5px"}).html("<ul>") 116 .window({ 117 width:\'500\', 118 height:"450", 119 modal:true, 120 closed:true, 121 iconCls:\'icon-save\', 122 title:\'选择类目\', 123 onOpen : function(){ 124 var _win = this; 125 $("ul",_win).tree({ 126 url:\'/item/cat/list\', 127 animate:true, 128 onClick : function(node){ 129 if($(this).tree("isLeaf",node.target)){ 130 // 填写到cid中 131 _ele.parent().find("[name=cid]").val(node.id); 132 _ele.next().text(node.text).attr("cid",node.id); 133 $(_win).window(\'close\'); 134 if(data && data.fun){ 135 data.fun.call(this,node); 136 } 137 } 138 } 139 }); 140 }, 141 onClose : function(){ 142 $(this).window("destroy"); 143 } 144 }).window(\'open\'); 145 }); 146 }); 147 }, 148 149 createEditor : function(select){ 150 return KindEditor.create(select, TT.kingEditorParams); 151 }, 152 153 /** 154 * 创建一个窗口,关闭窗口后销毁该窗口对象。<br/> 155 * 156 * 默认:<br/> 157 * width : 80% <br/> 158 * height : 80% <br/> 159 * title : (空字符串) <br/> 160 * 161 * 参数:<br/> 162 * width : <br/> 163 * height : <br/> 164 * title : <br/> 165 * url : 必填参数 <br/> 166 * onLoad : function 加载完窗口内容后执行<br/> 167 * 168 * 169 */ 170 createWindow : function(params){ 171 $("<div>").css({padding:"5px"}).window({ 172 width : params.width?params.width:"80%", 173 height : params.height?params.height:"80%", 174 modal:true, 175 title : params.title?params.title:"", 176 href : params.url, 177 onClose : function(){ 178 $(this).window("destroy"); 179 }, 180 onLoad : function(){ 181 if(params.onLoad){ 182 params.onLoad.call(this); 183 } 184 } 185 }).window("open"); 186 }, 187 188 closeCurrentWindow : function(){ 189 $(".panel-tool-close").click(); 190 }, 191 192 changeItemParam : function(node,formId){ 193 $.getJSON("/item/param/query/itemcatid/" + node.id,function(data){ 194 if(data.status == 200 && data.data){ 195 $("#"+formId+" .params").show(); 196 var paramData = JSON.parse(data.data.paramData); 197 var html = "<ul>"; 198 for(var i in paramData){ 199 var pd = paramData[i]; 200 html+="<li><table>"; 201 html+="<tr><td colspan=\\"2\\" class=\\"group\\">"+pd.group+"</td></tr>"; 202 203 for(var j in pd.params){ 204 var ps = pd.params[j]; 205 html+="<tr><td class=\\"param\\"><span>"+ps+"</span>: </td><td><input autocomplete=\\"off\\" type=\\"text\\"/></td></tr>"; 206 } 207 208 html+="</li></table>"; 209 } 210 html+= "</ul>"; 211 $("#"+formId+" .params td").eq(1).html(html); 212 }else{ 213 $("#"+formId+" .params").hide(); 214 $("#"+formId+" .params td").eq(1).empty(); 215 } 216 }); 217 }, 218 getSelectionsIds : function (select){ 219 var list = $(select); 220 var sels = list.datagrid("getSelections"); 221 var ids = []; 222 for(var i in sels){ 223 ids.push(sels[i].id); 224 } 225 ids = ids.join(","); 226 return ids; 227 }, 228 229 /** 230 * 初始化单图片上传组件 <br/> 231 * 选择器为:.onePicUpload <br/> 232 * 上传完成后会设置input内容以及在input后面追加<img> 233 */ 234 initOnePicUpload : function(){ 235 $(".onePicUpload").click(function(){ 236 var _self = $(this); 237 KindEditor.editor(TT.kingEditorParams).loadPlugin(\'image\', function() { 238 this.plugin.imageDialog({ 239 showRemote : false, 240 clickFn : function(url, title, width, height, border, align) { 241 var input = _self.siblings("input"); 242 input.parent().find("img").remove(); 243 input.val(url); 244 input.after("<a href=\'"+url+"\' target=\'_blank\'><img src=\'"+url+"\' width=\'80\' height=\'50\'/></a>"); 245 this.hideDialog(); 246 } 247 }); 248 }); 249 }); 250 } 251 }; 252
2:后台的逻辑实现
2-1: ftp配置文件
1 FTP_ADDRESS=192.168.1.5 2 FTP_PORT=21 3 FTP_USERNAME=ftpuser 4 FTP_PASSWORD=123456 5 FTP_BASEPATH=/home/ftpuser/www/images/ 6 IMAGE_BASE_URL=http://192.168.1.5/images/ 7
引入到SpringMVC.xml配置文件中
2-2:SpringMvc.xml的实现配置
1 2 <!-- 定义文件上传解析器 --> 3 <bean id="multipartResolver" 4 class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> 5 <!-- 设定默认编码 --> 6 <property name="defaultEncoding" value="UTF-8"></property> 7 <!-- 设定文件上传的最大值5MB,5*1024*1024 --> 8 <property name="maxUploadSize" value="5242880"></property> 9 </bean> 10 11
2-3:controller层实现:
1 package com.taotao.controller; 2 3 import java.util.Map; 4 5 import org.springframework.beans.factory.annotation.Autowired; 6 import org.springframework.stereotype.Controller; 7 import org.springframework.web.bind.annotation.RequestMapping; 8 import org.springframework.web.bind.annotation.ResponseBody; 9 import org.springframework.web.multipart.MultipartFile; 10 11 import com.taotao.common.utils.JsonUtils; 12 import com.taotao.service.PictureService; 13 14 /** 15 * 16 * @ClassName: PictureController 17 * @Description:上传图片处理 18 * @author: 刘军/shall_liu(1136808529@qq.com) 19 * @date: 2017年8月26日 下午4:03:42 20 * 21 * @Copyright: 2017 22 */ 23 @Controller 24 public class PictureController { 25 26 @Autowired 27 private PictureService pictureService; 用mvc框架中页面 用的 Jquery,在使用dialog是 使用 TinyMce的 图片上传以及富文本编辑器,springMVC -- 整合UEditor(富文本编辑器)