fastDFSå®æå¾çä¸ä¼ 并åæ¾
éæ±åæ
å¨ååå½å
¥çé¢å®ç°å¤å¾çä¸ä¼
å½ç¨æ·ç¹å»æ°å»ºæé®ï¼å¼¹åºä¸ä¼ çªå£
å端代ç ï¼maven项ç®ï¼
å·¥å
·ç±»
ï¼1ï¼commonå·¥ç¨pom.xmlå¼å
¥ä¾èµ
<!-- æ件ä¸ä¼ ç»ä»¶ -->
<dependency>
<groupId>org.csource.fastdfs</groupId>
<artifactId>fastdfs</artifactId>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
</dependency>
ï¼2ï¼å°fastDFSå·¥å ·ç±»FastDFSClient.java æ·è´å°commonå·¥ç¨(代ç å¨æä¸é¢)
é ç½®æ件
ï¼1ï¼å°fastDFSé
ç½®æ件 fdfs_client.conf æ·è´å°shop-webå·¥ç¨configæ件夹ï¼æä¸é¢ï¼
ï¼2ï¼å¨shop-webå·¥ç¨application.propertiesæ·»å é
ç½®(fastDFSæå¡å¨å°å)
FILE_SERVER_URL=http://192.168.25.153/
ï¼3ï¼å¨shop-webå·¥ç¨springmvc.xmlæ·»å é ç½®
<!-- é
ç½®å¤åªä½è§£æå¨ -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8"></property>
<!-- 设å®æ件ä¸ä¼ çæ大å¼5MBï¼5*1024*1024(大å°èªå·±å®ä¹) -->
<property name="maxUploadSize" value="5242880"></property>
</bean>
æ§å¶å±
å¨shop-webæ°å»ºUploadController.java
package com.pinyougou.shop.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import entity.Result;
import util.FastDFSClient;
/**
* æ件ä¸ä¼ Controller
* @author Administrator
*
*/
@RestController
public class UploadController {
@Value("${FILE_SERVER_URL}")
private String FILE_SERVER_URL;//æ件æå¡å¨å°å
@RequestMapping("/upload")
public Result upload( MultipartFile file){
//1ãåæ件çæ©å±å
String originalFilename = file.getOriginalFilename();
String extName = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
try {
//2ãå建ä¸ä¸ª FastDFS ç客æ·ç«¯
FastDFSClient fastDFSClient = new FastDFSClient("classpath:config/fdfs_client.conf");
//3ãæ§è¡ä¸ä¼ å¤ç
String path = fastDFSClient.uploadFile(file.getBytes(), extName);
//4ãæ¼æ¥è¿åç url å ip å°åï¼æ¼è£
æå®æ´ç url
String url = FILE_SERVER_URL + path;
return new Result(true,url);
} catch (Exception e) {
e.printStackTrace();
return new Result(false, "ä¸ä¼ 失败");
}
}
}
å端代ç
1 æå¡å±
ï¼1ï¼å¨shop-webå·¥ç¨å建uploadService.js
//æ件ä¸ä¼ æå¡å±
app.service("uploadService",function($http){
this.uploadFile=function(){
var formData=new FormData();//æ¯HTML5ä¸æ°å¢çä¸ä¸ªç±»ï¼ä¸é¨ç¨äºæ件ä¸ä¼
formData.append("file",file.files[0]); //file代表æ件ä¸ä¼ æ¡çnameï¼.files[0]代表å页é¢ç第ä¸ä¸ªæ件ä¸ä¼ æ¡
return $http({ //angularjsçå¦ä¸ç§åæ³
method:'POST',
url:"../upload.do",
data: formData, //formDataä½ä¸ºè½½ä½ä¸ä¼ æ件
headers: {'Content-Type':undefined}, //头信æ¯è®¾ç½®ä¸ºä¸æå®ç±»åï¼é»è®¤æ¯json
transformRequest: angular.identity //表示对æ´ä¸ªè¡¨åè¿è¡äºè¿å¶åºåå
});
}
});
anjularjs对äºpoståget请æ±é»è®¤çContent-Type header æ¯application/jsonãéè¿è®¾ç½®âContent-Typeâ: undefinedï¼è¿æ ·æµè§å¨ä¼å¸®æ们æContent-Type 设置为 multipart/form-data.
éè¿è®¾ç½® transformRequest: angular.identity ï¼anjularjs transformRequest function å°åºååæ们çformdata object.
ï¼2ï¼å°uploadServiceæå¡æ³¨å ¥å°goodsController ä¸
//ååæ§å¶å±ï¼å家åå°ï¼
app.controller('goodsController' ,function($scope,$controller ,goodsService,itemCatService,uploadService){
ï¼3ï¼å¨goods_edit.htmlå¼å ¥js
<script type="text/javascript" src="../js/base.js"> </script>
<script type="text/javascript" src="../js/service/goodsService.js"> </script>
<script type="text/javascript" src="../js/service/itemCatService.js"> </script>
<script type="text/javascript" src="../js/service/uploadService.js"> </script>
<script type="text/javascript" src="../js/controller/baseController.js"> </script>
<script type="text/javascript" src="../js/controller/goodsController.js"> </script>
ä¸ä¼ å¾ç
ï¼1ï¼goodsControllerç¼å代ç
/**
* ä¸ä¼ å¾ç
*/
$scope.uploadFile=function(){
uploadService.uploadFile().success(
function(response) {
if(response.success){//å¦æä¸ä¼ æåï¼ååºurl
$scope.image_entity.url=response.message;//设置æ件å°å
}else{
alert(response.message);
}
}).error(function() {
alert("ä¸ä¼ åçé误");
});
};
ï¼2ï¼å¨HTMLä¸ä¿®æ¹å¾çä¸ä¼ çªå£ï¼è°ç¨ä¸ä¼ æ¹æ³ï¼åæ¾ä¸ä¼ å¾ç
<div class="modal-body">
<table class="table table-bordered table-striped">
<tr>
<td>é¢è²</td>
<td><input class="form-control" placeholder="é¢è²" ng-model="image_entity.color"> </td>
</tr>
<tr>
<td>ååå¾ç</td>
<td>
<table>
<tr>
<td>
<input type="file" id="file" />
<button class="btn btn-primary" type="button" ng-click="uploadFile()">
ä¸ä¼
</button>
</td>
<td>
<img src="{{image_entity.url}}" width="200px" height="200px">
</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
ï¼3ï¼ä¿®æ¹æ°å»ºæé®(åå§åæ¸ ç©ºæ°æ®)
<button type="button" class="btn btn-default" title="æ°å»º" data-target="#uploadModal" data-toggle="modal" ng-click="image_entity={}" ><i class="fa fa-file-o"></i> æ°å»º</button>
åä¸æ®µè½å¹¶æµè¯
追å æ¾ç¤ºå¾çå表
ï¼1ï¼å¨goodsController.jså¢å æ¹æ³
$scope.entity={goods:{},goodsDesc:{itemImages:[]}};//å®ä¹é¡µé¢å®ä½ç»æ
//æ·»å å¾çå表
$scope.add_image_entity=function(){
$scope.entity.goodsDesc.itemImages.push($scope.image_entity);
}
ï¼2ï¼ä¿®æ¹ä¸ä¼ çªå£çä¿åæé®
3 å¾çå表
ï¼1ï¼å¨goodsController.jså¢å æ¹æ³
$scope.entity={goods:{},goodsDesc:{itemImages:[]}};//å®ä¹é¡µé¢å®ä½ç»æ
//æ·»å å¾çå表
$scope.add_image_entity=function(){
$scope.entity.goodsDesc.itemImages.push($scope.image_entity);
}
<button class="btn btn-success" ng-click="add_image_entity()" data-dismiss="modal" aria-hidden="true">ä¿å</button>
ï¼3ï¼éåå¾çå表
<tr ng-repeat="pojo in entity.goodsDesc.itemImages">
<td>{{pojo.color}}</td>
<td><img alt="" src="{{pojo.url}}" width="100px" height="100px"></td>
<td><button type="button" class="btn btn-default" title="å é¤" ><i class="fa fa-trash-o"></i> å é¤</button></td>
</tr>
移é¤å¾ç
å¨goodsController.jså¢å 代ç
//å表ä¸ç§»é¤å¾ç
$scope.remove_image_entity=function(index){
$scope.entity.goodsDesc.itemImages.splice(index,1);
}
ä¿®æ¹å表ä¸çå é¤æé®
<button type="button" class="btn btn-default" title="å é¤" ng-click="remove_image_entity($index)"><i class="fa fa-trash-o"></i> å é¤</button>
ä¸ä»£ç
shop-web项ç®ç»æå¦ä¸ï¼commonæ¯åç¬ä¸é¡¹ç®ï¼å¼å
¥commonå项ç®çä¾èµå³å¯
HTML代ç
<!DOCTYPE html>
<html>
<head>
<!-- 页é¢meta -->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>ååç¼è¾</title>
<!-- Tell the browser to be responsive to screen width -->
<meta content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" name="viewport">
<link rel="stylesheet" href="../plugins/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="../plugins/adminLTE/css/AdminLTE.css">
<link rel="stylesheet" href="../plugins/adminLTE/css/skins/_all-skins.min.css">
<link rel="stylesheet" href="../css/style.css">
<script src="../plugins/jQuery/jquery-2.2.3.min.js"></script>
<script src="../plugins/bootstrap/js/bootstrap.min.js"></script>
<!-- å¯ææ¬ç¼è¾å¨ -->
<link rel="stylesheet" href="../plugins/kindeditor/themes/default/default.css" />
<script charset="utf-8" src="../plugins/kindeditor/kindeditor-min.js"></script>
<script charset="utf-8" src="../plugins/kindeditor/lang/zh_CN.js"></script>
<script type="text/javascript" src="../plugins/angularjs/angular.min.js"></script>
<script type="text/javascript" src="../js/base.js"></script>
<script type="text/javascript" src="../js/service/goodsService.js"></script>
<script type="text/javascript" src="../js/service/uploadService.js"></script>
<script type="text/javascript" src="../js/controller/baseController.js"></script>
<script type="text/javascript" src="../js/controller/goodsController.js"></script>
</head>
<body class="hold-transition skin-red sidebar-mini" ng-app="zidingyi" ng-controller="goodsController">
<!-- æ£æåºå -->
<section class="content">
<div class="box-body">
<!--tab页-->
<div class="nav-tabs-custom">
<!--tab头-->
<ul class="nav nav-tabs">
<li class="active">
<a href="#home" data-toggle="tab">åååºæ¬ä¿¡æ¯</a>
</li>
<li >
<a href="#pic_upload" data-toggle="tab">ååå¾ç</a>
</li>
<li >
<a href="#customAttribute" data-toggle="tab">æ©å±å±æ§</a>
</li>
<li >
<a href="#spec" data-toggle="tab" >è§æ ¼</a>
</li>
</ul>
<!--tab头/-->
<!--tabå
容-->
<div class="tab-content">
<!--表åå
容-->
<div class="tab-pane active" id="home">
<div class="row data-type">
<div class="col-md-2 title">åååç±»</div>
<div class="col-md-10 data">
<table>
<tr>
<td>
<select class="form-control" >
</select>
</td>
<td>
<select class="form-control select-sm" ></select>
</td>
<td>
<select class="form-control select-sm" ></select>
</td>
<td>
模æ¿ID:19
</td>
</tr>
</table>
</div>
<div class="col-md-2 title">ååå称</div>
<div class="col-md-10 data">
<input type="text" class="form-control" ng-model="entity.goods.goodsName" placeholder="ååå称" value="">
</div>
<div class="col-md-2 title">åç</div>
<div class="col-md-10 data">
<select class="form-control" ></select>
</div>
<div class="col-md-2 title">å¯æ é¢</div>
<div class="col-md-10 data">
<input type="text" class="form-control" ng-model="entity.goods.caption" placeholder="å¯æ é¢" value="">
</div>
<div class="col-md-2 title">ä»·æ ¼</div>
<div class="col-md-10 data">
<div class="input-group">
<span class="input-group-addon">¥</span>
<input type="text" class="form-control" ng-model="entity.goods.price" placeholder="ä»·æ ¼" value="">
</div>
</div>
<div class="col-md-2 title editer">ååä»ç»</div>
<div class="col-md-10 data editer">
<textarea name="content" style="width:800px;height:400px;visibility:hidden;" ></textarea>
</div>
<div class="col-md-2 title rowHeight2x">å
è£
å表</div>
<div class="col-md-10 data rowHeight2x">
<textarea rows="4" class="form-control" ng-model="entity.goodsDesc.packageList" placeholder="å
è£
å表"></textarea>
</div>
<div class="col-md-2 title rowHeight2x">å®åæå¡</div>
<div class="col-md-10 data rowHeight2x">
<textarea rows="4" class="form-control" ng-model="entity.goodsDesc.saleService" placeholder="å®åæå¡"></textarea>
</div>
</div>
</div>
<!--å¾çä¸ä¼ -->
<div class="tab-pane" id="pic_upload">
<div class="row data-type">
<!-- é¢è²å¾ç -->
<div class="btn-group">
<button type="button" class="btn btn-default" title="æ°å»º" data-target="#uploadModal" ng-click="image_entity={}" data-toggle="modal" ><i class="fa fa-file-o"></i> æ°å»º</button>
</div>
<table class="table table-bordered table-striped table-hover dataTable">
<thead>
<tr>
<th class="sorting">é¢è²</th>
<th class="sorting">å¾ç</th>
<th class="sorting">æä½</th>
</thead>
<tbody>
<tr ng-repeat="pojo in entity.goodsDesc.itemImages">
<td>
{{pojo.color}}
</td>
<td>
<img alt="" src="{{pojo.url}}" width="100px" height="100px">
</td>
<td> <button type="button" class="btn btn-default" title="å é¤" ng-click="remove_image_entity($index)" ><i class="fa fa-trash-o"></i> å é¤</button></td>
</tr>
</tbody>
</table>
</div>
</div>
<!--æ©å±å±æ§-->
<div class="tab-pane" id="customAttribute">
<div class="row data-type">
<div>
<div class="col-md-2 title">æ©å±å±æ§1</div>
<div class="col-md-10 data">
<input class="form-control" placeholder="æ©å±å±æ§1">
</div>
</div>
<div>
<div class="col-md-2 title">æ©å±å±æ§2</div>
<div class="col-md-10 data">
<input class="form-control" placeholder="æ©å±å±æ§2">
</div>
</div>
</div>
</div>
<!--è§æ ¼-->
<div class="tab-pane" id="spec">
<div class="row data-type">
<div class="col-md-2 title">æ¯å¦å¯ç¨è§æ ¼</div>
<div class="col-md-10 data">
<input type="checkbox" >
</div>
</div>
<p>
<div>
<div class="row data-type">
<div>
<div class="col-md-2 title">å±å¹å°ºå¯¸</div>
<div class="col-md-10 data">
<span>
<input type="checkbox" >4.0
</span>
<span>
<input type="checkbox" >4.5
</span>
<span>
<input type="checkbox" >5.0
</span>
</div>
</div>
<div>
<div class="col-md-2 title">ç½ç»å¶å¼</div>
<div class="col-md-10 data">
<span>
<input type="checkbox" >2G
</span>
<span>
<input type="checkbox" >3G
</span>
<span>
<input type="checkbox" >4G
</span>
</div>
</div>
</div>
<div class="row data-type">
<table class="table table-bordered table-striped table-hover dataTable">
<thead>
<tr>
<th class="sorting">å±å¹å°ºå¯¸</th>
<th class="sorting">ç½ç»å¶å¼</th>
<th class="sorting">ä»·æ ¼</th>
<th class="sorting">åºå</th>
<th class="sorting">æ¯å¦å¯ç¨</th>
<th class="sorting">æ¯å¦é»è®¤</th>
</tr>
</thead>
<tbody>
<tr>
<td>
4.0
</td>
<td>
3G
</td>
<td>
<input class="form-control" placeholder="ä»·æ ¼">
</td>
<td>
<input class="form-control" placeholder="åºåæ°é">
</td>
<td>
<input type="checkbox" >
</td>
<td>
<input type="checkbox" >
</td>
</tr>
<tr>
<td>
4.0
</td>
<td>
4G
</td>
<td>
<input class="form-control" placeholder="ä»·æ ¼">
</td>
<td>
<input class="form-control" placeholder="åºåæ°é">
</td>
<td>
<input type="checkbox" >
</td>
<td>
<input type="checkbox" >
</td>
</tr>
<tr>
<td>
5.0
</td>
<td>
3G
</td>
<td>
<input class="form-control" placeholder="ä»·æ ¼">
</td>
<td>
<input class="form-control" placeholder="åºåæ°é">
</td>
<td>
<input type="checkbox" >
</td>
<td>
<input type="checkbox" >
</td>
</tr>
<tr>
<td>
5.0
</td>
<td>
4G
</td>
<td>
<input class="form-control" placeholder="ä»·æ ¼">
</td>
<td>
<input class="form-control" placeholder="åºåæ°é">
</td>
<td>
<input type="checkbox" >
</td>
<td>
<input type="checkbox" >
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<!--tabå
容/-->
<!--表åå
容/-->
</div>
</div>
<div class="btn-toolbar list-toolbar">
<button class="btn btn-primary" ng-click="add()"><i class="fa fa-save"></i>ä¿å</button>
<button class="btn btn-default" >è¿åå表</button>
</div>
</section>
<!-- ä¸ä¼ çªå£ -->
<div class="modal fade" id="uploadModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog" >
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="myModalLabel">ä¸ä¼ ååå¾ç</h3>
</div>
<div class="modal-body">
<table class="table table-bordered table-striped">
<tr>
<td>é¢è²</td>
<td><input class="form-control" placeholder="é¢è²" ng-model="image_entity.color"> </td>
</tr>
<tr>
<td>ååå¾ç</td>
<td>
<table>
<tr>
<td>
<input type="file" id="file" />
<button class="btn btn-primary" type="button" ng-click="uploadFile()">
ä¸ä¼
</button>
</td>
<td>
<img src="{{image_entity.url}}" width="200px" height="200px">
</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
<div class="modal-footer">
<button class="btn btn-success" data-dismiss="modal" aria-hidden="true" ng-click="add_image_entity()">ä¿å</button>
<button class="btn btn-default" data-dismiss="modal" aria-hidden="true">å
³é</button>
</div>
</div>
</div>
</div>
<!-- æ£æåºå /-->
<script type="text/javascript">
var editor;
KindEditor.ready(function(K) {
editor = K.create('textarea[name="content"]', {
allowFileManager : true
});
});
</script>
</body>
</html>
- FastDFSClient
package util;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.ClientGlobal;
import org.csource.fastdfs.StorageClient1;
import org.csource.fastdfs.StorageServer;
import org.csource.fastdfs.TrackerClient;
import org.csource.fastdfs.TrackerServer;
public class FastDFSClient {
private TrackerClient trackerClient = null;
private TrackerServer trackerServer = null;
private StorageServer storageServer = null;
private StorageClient1 storageClient = null;
public FastDFSClient(String conf) throws Exception {
if (conf.contains("classpath:")) {
conf = conf.replace("classpath:", this.getClass().getResource("/").getPath());
}
ClientGlobal.init(conf);
trackerClient = new TrackerClient();
trackerServer = trackerClient.getConnection();
storageServer = null;
storageClient = new StorageClient1(trackerServer, storageServer);
}
/**
* ä¸ä¼ æ件æ¹æ³
* <p>Title: uploadFile</p>
* <p>Description: </p>
* @param fileName æ件å
¨è·¯å¾
* @param extName æ件æ©å±åï¼ä¸å
å«ï¼.ï¼
* @param metas æ件æ©å±ä¿¡æ¯
* @return
* @throws Exception
*/
public String uploadFile(String fileName, String extName, NameValuePair[] metas) throws Exception {
String result = storageClient.upload_file1(fileName, extName, metas);
return result;
}
public String uploadFile(String fileName) throws Exception {
return uploadFile(fileName, null, null);
}
public String uploadFile(String fileName, String extName) throws Exception {
return uploadFile(fileName, extName, null);
}
/**
* ä¸ä¼ æ件æ¹æ³
* <p>Title: uploadFile</p>
* <p>Description: </p>
* @param fileContent æ件çå
容ï¼åèæ°ç»
* @param extName æ件æ©å±å
* @param metas æ件æ©å±ä¿¡æ¯
* @return
* @throws Exception
*/
public String uploadFile(byte[] fileContent, String extName, NameValuePair[] metas) throws Exception {
String result = storageClient.upload_file1(fileContent, extName, metas);
return result;
}
public String uploadFile(byte[] fileContent) throws Exception {
return uploadFile(fileContent, null, null);
}
public String uploadFile(byte[] fileContent, String extName) throws Exception {
return uploadFile(fileContent, extName, null);
}
}
fdfs_client.confé ç½®æ件
注æä¿®æ¹tracker_serverå°åï¼tracker_server=192.168.25.153:22122(fastDFSæå¡å¨çå°å)
# connect timeout in seconds
# default value is 30s
connect_timeout=30
# network timeout in seconds
# default value is 30s
network_timeout=60
# the base path to store log files
base_path=/home/fastdfs
# tracker_server can ocur more than once, and tracker_server format is
# "host:port", host can be hostname or ip address
tracker_server=192.168.25.153:22122
#standard log level as syslog, case insensitive, value list:
### emerg for emergency
### alert
### crit for critical
### error
### warn for warning
### notice
### info
### debug
log_level=info
# if use connection pool
# default value is false
# since V4.05
use_connection_pool = false
# connections whose the idle time exceeds this time will be closed
# unit: second
# default value is 3600
# since V4.05
connection_pool_max_idle_time = 3600
# if load FastDFS parameters from tracker server
# since V4.05
# default value is false
load_fdfs_parameters_from_tracker=false
# if use storage ID instead of IP address
# same as tracker.conf
# valid only when load_fdfs_parameters_from_tracker is false
# default value is false
# since V4.05
use_storage_id = false
# specify storage ids filename, can use relative or absolute path
# same as tracker.conf
# valid only when load_fdfs_parameters_from_tracker is false
# since V4.05
storage_ids_filename = storage_ids.conf
#HTTP settings
http.tracker_server_port=80
#use "#include" directive to include HTTP other settiongs
##include http.conf