• SpringMvc + Jsp+ 富文本 kindeditor 进行 图片ftp上传nginx服务器 实现


    一:html 原生态的附件上传

    image

    image

    二:实现逻辑分析;

    1.1.1 需求分析

    Common.js

    1、绑定事件

    clip_image002

    2、初始化参数

    clip_image004

    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

    image

    image

    7:  Controller

    image

    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=" 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=" 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; 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="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     				'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."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配置文件中

    image

    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;
     28 
     29 	/**
     30 	 *
     31 	 * @Title: pictureUpload
     32 	 * @Description:  接收图片上传服务
     33 	 * @param: @param uploadFile
     34 	 * @param: @return
     35 	 * @return: Map
     36 	 * @throws
     37 	 */
     38 	@RequestMapping("/pic/upload")
     39 	@ResponseBody
     40 	public String pictureUpload(MultipartFile uploadFile){
     41 		Map result =pictureService.uploadPicture(uploadFile);
     42 		//为了保证能的兼容性,需要把  Result转换成json格式的字符串
     43 	    String  json=	JsonUtils.objectToJson(result);
     44 		return json;
     45 	}
     46 
     47 
     48 
     49 
     50 }
     51 

    2_-4: service 层实现

      1 package com.taotao.service;
      2 
      3 import java.util.Map;
      4 
      5 import org.springframework.web.multipart.MultipartFile;
      6 
      7 /**
      8  *
      9  * @ClassName:  PictureService
     10  * @Description: 图片生成接口
     11  *
     12  * @author:  刘军/shall_liu(1136808529@qq.com)
     13  * @date:   2017年8月26日 下午2:29:35
     14  *
     15  * @Copyright: 2017
     16  */
     17 public interface PictureService {
     18 
     19 	/**
     20 	 *
     21 	 * @Title: uploadPicture
     22 	 * @Description:  生成图片接口
     23 	 * @param: @param uploadFile
     24 	 * @param: @return
     25 	 * @return: Map
     26 	 * @throws
     27 	 */
     28 	Map uploadPicture(MultipartFile uploadFile);
     29 
     30 
     31 
     32 }
     33 
      1 package com.taotao.service.impl;
      2 
      3 import java.io.IOException;
      4 import java.util.HashMap;
      5 import java.util.Map;
      6 
      7 import org.apache.ibatis.annotations.ResultMap;
      8 import org.joda.time.DateTime;
      9 import org.springframework.beans.factory.annotation.Value;
     10 import org.springframework.stereotype.Service;
     11 import org.springframework.web.multipart.MultipartFile;
     12 
     13 import com.mysql.jdbc.ResultSetMetaData;
     14 import com.taotao.common.utils.FtpUtil;
     15 import com.taotao.common.utils.IDUtils;
     16 import com.taotao.service.PictureService;
     17 /**
     18  *
     19  * @ClassName:  PictureServiceImpl
     20  * @Description:图片上传 服务
     21  * @author:  刘军/shall_liu(1136808529@qq.com)
     22  * @date:   2017年8月26日 下午2:33:25
     23  *
     24  * @Copyright: 2017
     25  */
     26 @Service
     27 public class PictureServiceImpl  implements PictureService{
     28    /**
     29 	 * 实现原理:
     30 	 * 利用了springMvc的加载properties的一套实现工具的机制
     31 	 * 使用注解@value 自动注入properties的参数信息
     32 	 *
     33 	 * ftp ip 访问地址
     34 	 */
     35 	@Value("${FTP_ADDRESS}")
     36 	private String FTP_ADDRESS;
     37 	/**
     38 	 * ftp 服务端口
     39 	 */
     40 	@Value("${FTP_PORT}")
     41 	private String FTP_PORT;
     42 	/**
     43 	 * ftp 登录用户名
     44 	 */
     45 	@Value("${FTP_USERNAME}")
     46 	private String FTP_USERNAME;
     47 	/**
     48 	 * ftp 登录密码
     49 	 */
     50 	@Value("${FTP_PASSWORD}")
     51 	private String FTP_PASSWORD;
     52 	/**
     53 	 * ftp 保存文件的跟文件路径
     54 	 */
     55 	@Value("${FTP_BASEPATH}")
     56 	private String FTP_BASEPATH;
     57 	/**
     58 	 * 图片服务器的基础URL
     59 	 */
     60 	@Value("${IMAGE_BASE_URL}")
     61 	private String IMAGE_BASE_URL;
     62 
     63 
     64 
     65 	 /**
     66 	  *
     67 	  * <p>Title: uploadPicture</p>
     68 	  * <p>Description: </p>  图片上传的实现
     69 	  * @param uploadFile
     70 	  * @return
     71 	  * @see com.taotao.service.PictureService#uploadPicture(org.springframework.web.multipart.MultipartFile)
     72 	  */
     73 	@Override
     74 	public Map uploadPicture(MultipartFile uploadFile) {
     75 		Map  resultMap =new HashMap<>();
     76 		try {
     77 			/*
     78 			 * 生成一个新的文件名
     79 			 */
     80 			//取原文件名
     81 			  String  oldName=uploadFile.getOriginalFilename();
     82 			 //生成新文件名
     83 			  String newName = IDUtils.genImageName();
     84 			  newName=newName+oldName.substring(oldName.indexOf("."), oldName.length());
     85 			  // 图片上传 
     86 			  String imagePath=new DateTime().toString("/yyyy/MM/dd");
     87 			  System.out.println(FTP_PORT);
     88 			 boolean result= FtpUtil.uploadFile(FTP_ADDRESS,Integer.parseInt(FTP_PORT.trim()) , FTP_USERNAME, FTP_PASSWORD, FTP_BASEPATH, imagePath, newName, uploadFile.getInputStream());
     89 			if(!result){
     90 				resultMap.put("error", 1);
     91 				resultMap.put("message", "文件上传失败");
     92 				return resultMap;
     93 			}
     94 			resultMap.put("error", 0);
     95 			resultMap.put("url", IMAGE_BASE_URL+imagePath+"/"+newName);
     96 
     97 			return resultMap ;
     98 		} catch (IOException e) {
     99 			resultMap.put("error", 1);
    100 			resultMap.put("message", "文件上传发生异常"+e.toString());
    101 			return resultMap;
    102 		}
    103 
    104 
    105 	}
    106 
    107 
    108 
    109 
    110 
    111 }

    2-5: dao 层

    无实现

    2-6:工具类

      1 package com.taotao.common.utils;
      2 
      3 import java.io.File;
      4 import java.io.FileInputStream;
      5 import java.io.FileNotFoundException;
      6 import java.io.FileOutputStream;
      7 import java.io.IOException;
      8 import java.io.InputStream;
      9 import java.io.OutputStream;
     10 
     11 import org.apache.commons.net.ftp.FTP;
     12 import org.apache.commons.net.ftp.FTPClient;
     13 import org.apache.commons.net.ftp.FTPFile;
     14 import org.apache.commons.net.ftp.FTPReply;
     15 
     16 /**
     17  *
     18  * @ClassName:  FtpUtil
     19  * @Description: ftp上传下载工具类
     20  *  来自传智播客
     21  * @author:  刘军/shall_liu(1136808529@qq.com)
     22  * @date:   2017年8月26日 下午7:10:41
     23  *
     24  * @Copyright: 2017
     25  */
     26 public class FtpUtil {
     27 
     28 	/**
     29 	 * Description: 向FTP服务器上传文件
     30 	 * @param host FTP服务器hostname
     31 	 * @param port FTP服务器端口
     32 	 * @param username FTP登录账号
     33 	 * @param password FTP登录密码
     34 	 * @param basePath FTP服务器基础目录
     35 	 * @param filePath FTP服务器文件存放路径。例如分日期存放:/2015/01/01。文件的路径为basePath+filePath
     36 	 * @param filename 上传到FTP服务器上的文件名
     37 	 * @param input 输入流
     38 	 * @return 成功返回true,否则返回false
     39 	 */
     40 	public static boolean uploadFile(String host, int port, String username, String password, String basePath,
     41 			String filePath, String filename, InputStream input) {
     42 		boolean result = false;
     43 		FTPClient ftp = new FTPClient();
     44 		try {
     45 			int reply;
     46 			ftp.connect(host, port);// 连接FTP服务器
     47 			// 如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器
     48 			ftp.login(username, password);// 登录
     49 			reply = ftp.getReplyCode();
     50 			if (!FTPReply.isPositiveCompletion(reply)) {
     51 				ftp.disconnect();
     52 				return result;
     53 			}
     54 			//切换到上传目录
     55 			if (!ftp.changeWorkingDirectory(basePath+filePath)) {
     56 				//如果目录不存在创建目录
     57 				String[] dirs = filePath.split("/");
     58 				String tempPath = basePath;
     59 				for (String dir : dirs) {
     60 					if (null == dir || "".equals(dir)) continue;
     61 					tempPath += "/" + dir;
     62 					if (!ftp.changeWorkingDirectory(tempPath)) {
     63 						if (!ftp.makeDirectory(tempPath)) {
     64 							return result;
     65 						} else {
     66 							ftp.changeWorkingDirectory(tempPath);
     67 						}
     68 					}
     69 				}
     70 			}
     71 			//设置上传文件的类型为二进制类型
     72 			ftp.setFileType(FTP.BINARY_FILE_TYPE);
     73 			//上传文件
     74 			if (!ftp.storeFile(filename, input)) {
     75 				return result;
     76 			}
     77 			input.close();
     78 			ftp.logout();
     79 			result = true;
     80 		} catch (IOException e) {
     81 			e.printStackTrace();
     82 		} finally {
     83 			if (ftp.isConnected()) {
     84 				try {
     85 					ftp.disconnect();
     86 				} catch (IOException ioe) {
     87 				}
     88 			}
     89 		}
     90 		return result;
     91 	}
     92 
     93 	/**
     94 	 * Description: 从FTP服务器下载文件
     95 	 * @param host FTP服务器hostname
     96 	 * @param port FTP服务器端口
     97 	 * @param username FTP登录账号
     98 	 * @param password FTP登录密码
     99 	 * @param remotePath FTP服务器上的相对路径
    100 	 * @param fileName 要下载的文件名
    101 	 * @param localPath 下载后保存到本地的路径
    102 	 * @return
    103 	 */
    104 	public static boolean downloadFile(String host, int port, String username, String password, String remotePath,
    105 			String fileName, String localPath) {
    106 		boolean result = false;
    107 		FTPClient ftp = new FTPClient();
    108 		try {
    109 			int reply;
    110 			ftp.connect(host, port);
    111 			// 如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器
    112 			ftp.login(username, password);// 登录
    113 			reply = ftp.getReplyCode();
    114 			if (!FTPReply.isPositiveCompletion(reply)) {
    115 				ftp.disconnect();
    116 				return result;
    117 			}
    118 			ftp.changeWorkingDirectory(remotePath);// 转移到FTP服务器目录
    119 			FTPFile[] fs = ftp.listFiles();
    120 			for (FTPFile ff : fs) {
    121 				if (ff.getName().equals(fileName)) {
    122 					File localFile = new File(localPath + "/" + ff.getName());
    123 
    124 					OutputStream is = new FileOutputStream(localFile);
    125 					ftp.retrieveFile(ff.getName(), is);
    126 					is.close();
    127 				}
    128 			}
    129 
    130 			ftp.logout();
    131 			result = true;
    132 		} catch (IOException e) {
    133 			e.printStackTrace();
    134 		} finally {
    135 			if (ftp.isConnected()) {
    136 				try {
    137 					ftp.disconnect();
    138 				} catch (IOException ioe) {
    139 				}
    140 			}
    141 		}
    142 		return result;
    143 	}
    144 
    145 	public static void main(String[] args) {
    146 		try {
    147 	        FileInputStream in=new FileInputStream(new File("D:\temp\image\gaigeming.jpg"));
    148 	        boolean flag = uploadFile("192.168.25.133", 21, "ftpuser", "ftpuser", "/home/ftpuser/www/images","/2015/01/21", "gaigeming.jpg", in);
    149 	        System.out.println(flag);
    150 	    } catch (FileNotFoundException e) {
    151 	        e.printStackTrace();
    152 	    }
    153 	}
    154 }
    155 
      1 package com.taotao.common.utils;
      2 
      3 import java.util.Random;
      4 
      5 /**
      6  *
      7  * @ClassName:  IDUtils
      8  * @Description:各种id生成策略
      9  * @author:  刘军/shall_liu(1136808529@qq.com)
     10  * @date:   2017年8月26日 下午2:49:33
     11  *
     12  * @Copyright: 2017
     13  */
     14 public class IDUtils {
     15 
     16 	/**
     17 	 * 图片名生成
     18 	 */
     19 	public static String genImageName() {
     20 		//取当前时间的长整形值包含毫秒
     21 		long millis = System.currentTimeMillis();//毫秒
     22 		//纳秒   1秒=1000毫秒=1000 X 1000 微秒 =1000 X 1000X 1000 纳秒 
     23 		//long millis = System.nanoTime(); 
     24 		//加上三位随机数
     25 		Random random = new Random();
     26 		int end3 = random.nextInt(999);
     27 		//如果不足三位前面补0
     28 		String str = millis + String.format("%03d", end3);
     29 
     30 		return str;
     31 	}
     32 
     33 	/**
     34 	 * 商品id生成
     35 	 */
     36 	public static long genItemId() {
     37 		//取当前时间的长整形值包含毫秒
     38 		long millis = System.currentTimeMillis();
     39 		//long millis = System.nanoTime();
     40 		//加上两位随机数
     41 		Random random = new Random();
     42 		int end2 = random.nextInt(99);
     43 		//如果不足两位前面补0
     44 		String str = millis + String.format("%02d", end2);
     45 		long id = new Long(str);
     46 		return id;
     47 	}
     48 
     49 	public static void main(String[] args) {
     50 		for(int i=0;i< 100;i++)
     51 		System.out.println(genItemId());
     52 	}
     53 }
     54 
      1 package com.taotao.common.utils;
      2 
      3 import java.util.List;
      4 
      5 import com.fasterxml.jackson.core.JsonProcessingException;
      6 import com.fasterxml.jackson.databind.JavaType;
      7 import com.fasterxml.jackson.databind.ObjectMapper;
      8 
      9 /**
     10  * 淘淘商城自定义响应结构
     11  */
     12 public class JsonUtils {
     13 
     14     // 定义jackson对象
     15     private static final ObjectMapper MAPPER = new ObjectMapper();
     16 
     17     /**
     18      * 将对象转换成json字符串。
     19      * <p>Title: pojoToJson</p>
     20      * <p>Description: </p>
     21      * @param data
     22      * @return
     23      */
     24     public static String objectToJson(Object data) {
     25     	try {
     26 			String string = MAPPER.writeValueAsString(data);
     27 			return string;
     28 		} catch (JsonProcessingException e) {
     29 			e.printStackTrace();
     30 		}
     31     	return null;
     32     }
     33 
     34     /**
     35      * 将json结果集转化为对象
     36      *
     37      * @param jsonData json数据
     38      * @param clazz 对象中的object类型
     39      * @return
     40      */
     41     public static <T> T jsonToPojo(String jsonData, Class<T> beanType) {
     42         try {
     43             T t = MAPPER.readValue(jsonData, beanType);
     44             return t;
     45         } catch (Exception e) {
     46         	e.printStackTrace();
     47         }
     48         return null;
     49     }
     50 
     51     /**
     52      * 将json数据转换成pojo对象list
     53      * <p>Title: jsonToList</p>
     54      * <p>Description: </p>
     55      * @param jsonData
     56      * @param beanType
     57      * @return
     58      */
     59     public static <T>List<T> jsonToList(String jsonData, Class<T> beanType) {
     60     	JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType);
     61     	try {
     62     		List<T> list = MAPPER.readValue(jsonData, javaType);
     63     		return list;
     64 		} catch (Exception e) {
     65 			e.printStackTrace();
     66 		}
     67 
     68     	return null;
     69     }
     70 
     71 }
     72 

    2-7:对于 linux环境下的nginx 服务器和ftp服务器的搭建 请查看以下文章:

    centos7_ linux : Nginx安装手册》、《CentOS7 搭建FTP服务器》、《centos7 nginx图片 服务器可以访问ftp用户上传的图片资源的配置

    四:效果展示:

    image

     

     

     

     

     

     

  • 相关阅读:
    MongoDB时间处理问题
    TextArea里Placeholder换行问题
    C# 文件与二进制流间的转换
    WPF图标旋转的动画
    ABP之本地化/多语言支持
    ABP之应用服务层Application
    ABP之创建实体
    关于Mapper not initialized的错误
    Request verb is GET. It should be Post(ABP使用api访问错误)
    在ABP模板工程中使用MySQL
  • 原文地址:https://www.cnblogs.com/ios9/p/JavaCode_SpringMvc_kindEditor_ftp_nginx_fileupload.html
Copyright © 2020-2023  润新知