一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術(shù)及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達式|C/C++|IOS|C#|Swift|Android|JavaScript|易語言|

服務器之家 - 編程語言 - Java教程 - Spring Boot整合FTPClient線程池的實現(xiàn)示例

Spring Boot整合FTPClient線程池的實現(xiàn)示例

2021-06-24 09:59hrabbits Java教程

這篇文章主要介紹了Spring Boot整合FTPClient線程池的實現(xiàn)示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

最近在寫一個ftp上傳工具,用到了apache的ftpclient,但是每個線程頻繁的創(chuàng)建和銷毀ftpclient對象對服務器的壓力很大,因此,此處最好使用一個ftpclient連接池。仔細翻了一下apache的api,發(fā)現(xiàn)它并沒有一個ftpclientpool的實現(xiàn),所以,不得不自己寫一個ftpclientpool。下面就大體介紹一下開發(fā)連接池的整個過程,供大家參考。

我們可以利用apache提供的common-pool包來協(xié)助我們開發(fā)連接池。而開發(fā)一個簡單的對象池,僅需要實現(xiàn)common-pool 包中的objectpool和poolableobjectfactory兩個接口即可。

線程池的意義

為了減少頻繁創(chuàng)建、銷毀對象帶來的性能消耗,我們可以利用對象池的技術(shù)來實現(xiàn)對象的復用。對象池提供了一種機制,它可以管理對象池中對象的生命周期,提供了獲取和釋放對象的方法,可以讓客戶端很方便的使用對象池中的對象。

pom引入依賴

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!-- ftpclient依賴包-->
   <dependency>
     <groupid>commons-net</groupid>
     <artifactid>commons-net</artifactid>
     <version>3.5</version>
   </dependency>
 
   <!-- 線程池-->
   <dependency>
     <groupid>commons-pool</groupid>
     <artifactid>commons-pool</artifactid>
     <version>1.6</version>
   </dependency>
 
   <dependency>
     <groupid>org.apache.commons</groupid>
     <artifactid>commons-pool2</artifactid>
     <version>2.0</version>
   </dependency>

創(chuàng)建ftp配置信息

在resources目錄下創(chuàng)建ftp.properties配置文件,目錄結(jié)構(gòu)如下:

Spring Boot整合FTPClient線程池的實現(xiàn)示例

添加如下的配置信息:

?
1
2
3
4
5
6
7
8
9
10
########### ftp用戶名稱 ###########
ftp.username=hrabbit
########### ftp用戶密碼 ###########
ftp.password=123456
########### ftp主機ip ###########
ftp.host=127.0.0.1
########### ftp主機端口號 ###########
ftp.port=21
########### 保存根路徑 ###########
ftp.baseurl=/

創(chuàng)建ftpproperties.java配置文件

加載配置內(nèi)容到spring中,配置信息基本延用我的就可以。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/**
 * ftp的配置信息
 * @auther: hrabbit
 * @date: 2018-12-03 2:06 pm
 * @description:
 */
@data
@component
@propertysource("classpath:ftp.properties")
@configurationproperties(prefix = "ftp")
public class ftpproperties {
 
  private string username;
 
  private string password;
 
  private string host;
 
  private integer port;
 
  private string baseurl;
 
  private integer passivemode = ftp.binary_file_type;
 
  private string encoding="utf-8";
 
  private int clienttimeout=120000;
 
  private int buffersize;
 
  private int transferfiletype=ftp.binary_file_type;
 
  private boolean renameuploaded;
 
  private int retrytime;
}

創(chuàng)建ftpclientpool線程池

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/**
 * 自定義實現(xiàn)ftp連接池
 * @auther: hrabbit
 * @date: 2018-12-03 3:40 pm
 * @description:
 */
@slf4j
@suppresswarnings("all")
public class ftpclientpool implements objectpool<ftpclient> {
 
  private static final int default_pool_size = 10;
 
  public blockingqueue<ftpclient> blockingqueue;
 
  private ftpclientfactory factory;
 
  public ftpclientpool(ftpclientfactory factory) throws exception {
    this(default_pool_size, factory);
  }
 
  public ftpclientpool(int poolsize, ftpclientfactory factory) throws exception {
    this.factory = factory;
    this.blockingqueue = new arrayblockingqueue<ftpclient>(poolsize);
    initpool(poolsize);
  }
 
  /**
   * 初始化連接池
   * @param maxpoolsize
   *         最大連接數(shù)
   * @throws exception
   */
  private void initpool(int maxpoolsize) throws exception {
    int count = 0;
    while(count < maxpoolsize) {
      this.addobject();
      count++;
    }
  }
 
  /**
   * 從連接池中獲取對象
   */
  @override
  public ftpclient borrowobject() throws exception {
    ftpclient client = blockingqueue.take();
    if(client == null) {
      client = factory.makeobject();
    } else if(!factory.validateobject(client)) {
      invalidateobject(client);
      client = factory.makeobject();
    }
    return client;
  }
 
  /**
   * 返還一個對象(鏈接)
   */
  @override
  public void returnobject(ftpclient client) throws exception {
    if ((client != null) && !blockingqueue.offer(client,2,timeunit.minutes)) {
      try {
        factory.destroyobject(client);
      } catch (exception e) {
        throw e;
      }
    }
  }
 
  /**
   * 移除無效的對象(ftp客戶端)
   */
  @override
  public void invalidateobject(ftpclient client) throws exception {
    blockingqueue.remove(client);
  }
 
  /**
   * 增加一個新的鏈接,超時失效
   */
  @override
  public void addobject() throws exception {
    blockingqueue.offer(factory.makeobject(), 2, timeunit.minutes);
  }
 
  /**
   * 重新連接
   */
  public ftpclient reconnect() throws exception {
    return factory.makeobject();
  }
 
  /**
   * 獲取空閑鏈接數(shù)(這里暫不實現(xiàn))
   */
  @override
  public int getnumidle() {
    return blockingqueue.size();
  }
 
  /**
   * 獲取正在被使用的鏈接數(shù)
   */
  @override
  public int getnumactive() {
    return default_pool_size - getnumidle();
  }
 
  @override
  public void clear() throws exception {
 
  }
 
  /**
   * 關(guān)閉連接池
   */
  @override
  public void close() {
    try {
      while(blockingqueue.iterator().hasnext()) {
        ftpclient client = blockingqueue.take();
        factory.destroyobject(client);
      }
    } catch(exception e) {
      log.error("close ftp client pool failed...{}", e);
    }
  }
 
  /**
   * 增加一個新的鏈接,超時失效
   */
  public void addobject(ftpclient ftpclient) throws exception {
    blockingqueue.put(ftpclient);
  }
}

創(chuàng)建一個ftpclientfactory工廠類

創(chuàng)建ftpclientfactory實現(xiàn)poolableobjectfactory的接口,ftpclient工廠類,通過ftpclient工廠提供ftpclient實例的創(chuàng)建和銷毀

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/**
 * ftpclient 工廠
 * @auther: hrabbit
 * @date: 2018-12-03 3:41 pm
 * @description:
 */
@slf4j
@suppresswarnings("all")
public class ftpclientfactory implements poolableobjectfactory<ftpclient> {
 
  private ftpproperties ftpproperties;
 
  public ftpclientfactory(ftpproperties ftpproperties) {
    this.ftpproperties = ftpproperties;
  }
 
  @override
  public ftpclient makeobject() throws exception {
    ftpclient ftpclient = new ftpclient();
    ftpclient.setcontrolencoding(ftpproperties.getencoding());
    ftpclient.setconnecttimeout(ftpproperties.getclienttimeout());
    try {
      ftpclient.connect(ftpproperties.gethost(), ftpproperties.getport());
      int reply = ftpclient.getreplycode();
      if (!ftpreply.ispositivecompletion(reply)) {
        ftpclient.disconnect();
        log.warn("ftpserver refused connection");
        return null;
      }
      boolean result = ftpclient.login(ftpproperties.getusername(), ftpproperties.getpassword());
      ftpclient.setfiletype(ftpproperties.gettransferfiletype());
      if (!result) {
        log.warn("ftpclient login failed... username is {}", ftpproperties.getusername());
      }
    } catch (exception e) {
      log.error("create ftp connection failed...{}", e);
      throw e;
    }
 
    return ftpclient;
  }
 
  @override
  public void destroyobject(ftpclient ftpclient) throws exception {
    try {
      if(ftpclient != null && ftpclient.isconnected()) {
        ftpclient.logout();
      }
    } catch (exception e) {
      log.error("ftp client logout failed...{}", e);
      throw e;
    } finally {
      if(ftpclient != null) {
        ftpclient.disconnect();
      }
    }
 
  }
 
  @override
  public boolean validateobject(ftpclient ftpclient) {
    try {
      return ftpclient.sendnoop();
    } catch (exception e) {
      log.error("failed to validate client: {}");
    }
    return false;
  }
 
  @override
  public void activateobject(ftpclient obj) throws exception {
    //do nothing
 
  }
 
  @override
  public void passivateobject(ftpclient obj) throws exception {
    //do nothing
 
  }
}

創(chuàng)建ftputils.java的工具類

ftputils.java中封裝了上傳、下載等方法,在項目啟動的時候,在@postconstruct注解的作用下通過執(zhí)行init()的方法,創(chuàng)建ftpclientfactory工廠中,并初始化了ftpclientpool線程池,這樣每次調(diào)用方法的時候,都直接從ftpclientpool中取出一個ftpclient對象

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
/**
 * @auther: hrabbit
 * @date: 2018-12-03 3:47 pm
 * @description:
 */
@slf4j
@component
public class ftputils {
 
  /**
   * ftp的連接池
   */
  @autowired
  public static ftpclientpool ftpclientpool;
  /**
   * ftpclient對象
   */
  public static ftpclient ftpclient;
 
 
  private static ftputils ftputils;
 
  @autowired
  private ftpproperties ftpproperties;
 
  /**
   * 初始化設置
   * @return
   */
  @postconstruct
  public boolean init() {
    ftpclientfactory factory = new ftpclientfactory(ftpproperties);
    ftputils = this;
    try {
      ftpclientpool = new ftpclientpool(factory);
    } catch (exception e) {
      e.printstacktrace();
      return false;
    }
    return true;
  }
 
 
  /**
   * 獲取連接對象
   * @return
   * @throws exception
   */
  public static ftpclient getftpclient() throws exception {
    //初始化的時候從隊列中取出一個連接
    if (ftpclient==null) {
      synchronized (ftpclientpool) {
        ftpclient = ftpclientpool.borrowobject();
      }
    }
    return ftpclient;
  }
 
 
  /**
   * 當前命令執(zhí)行完成命令完成
   * @throws ioexception
   */
  public void complete() throws ioexception {
    ftpclient.completependingcommand();
  }
 
  /**
   * 當前線程任務處理完成,加入到隊列的最后
   * @return
   */
  public void disconnect() throws exception {
    ftpclientpool.addobject(ftpclient);
  }
 
  /**
   * description: 向ftp服務器上傳文件
   *
   * @version1.0
   * @param remotefile
   *      上傳到ftp服務器上的文件名
   * @param input
   *      本地文件流
   * @return 成功返回true,否則返回false
   */
  public static boolean uploadfile(string remotefile, inputstream input) {
    boolean result = false;
    try {
      getftpclient();
      ftpclient.enterlocalpassivemode();
      result = ftpclient.storefile(remotefile, input);
      input.close();
      ftpclient.disconnect();
    } catch (exception e) {
      e.printstacktrace();
    }
    return result;
  }
 
  /**
   * description: 向ftp服務器上傳文件
   *
   * @version1.0
   * @param remotefile
   *      上傳到ftp服務器上的文件名
   * @param localfile
   *      本地文件
   * @return 成功返回true,否則返回false
   */
  public static boolean uploadfile(string remotefile, string localfile){
    fileinputstream input = null;
    try {
      input = new fileinputstream(new file(localfile));
    } catch (filenotfoundexception e) {
      e.printstacktrace();
    }
    return uploadfile(remotefile, input);
  }
 
  /**
   * 拷貝文件
   * @param fromfile
   * @param tofile
   * @return
   * @throws exception
   */
  public boolean copyfile(string fromfile, string tofile) throws exception {
    inputstream in=getfileinputstream(fromfile);
    getftpclient();
    boolean flag = ftpclient.storefile(tofile, in);
    in.close();
    return flag;
  }
 
  /**
   * 獲取文件輸入流
   * @param filename
   * @return
   * @throws ioexception
   */
  public static inputstream getfileinputstream(string filename) throws exception {
    bytearrayoutputstream fos=new bytearrayoutputstream();
    getftpclient();
    ftpclient.retrievefile(filename, fos);
    bytearrayinputstream in=new bytearrayinputstream(fos.tobytearray());
    fos.close();
    return in;
  }
 
  /**
   * description: 從ftp服務器下載文件
   *
   * @version1.0
   * @return
   */
  public static boolean downfile(string remotefile, string localfile){
    boolean result = false;
    try {
      getftpclient();
      outputstream os = new fileoutputstream(localfile);
      ftpclient.retrievefile(remotefile, os);
      ftpclient.logout();
      ftpclient.disconnect();
      result = true;
    } catch (exception e) {
      e.printstacktrace();
    } finally {
      try {
      } catch (exception e) {
        e.printstacktrace();
      }
    }
    return result;
  }
 
  /**
   * 從ftp中獲取文件流
   * @param filepath
   * @return
   * @throws exception
   */
  public static inputstream getinputstream(string filepath) throws exception {
    getftpclient();
    inputstream inputstream = ftpclient.retrievefilestream(filepath);
    return inputstream;
  }
 
  /**
   * ftp中文件重命名
   * @param fromfile
   * @param tofile
   * @return
   * @throws exception
   */
  public boolean rename(string fromfile,string tofile) throws exception {
    getftpclient();
    boolean result = ftpclient.rename(fromfile,tofile);
    return result;
  }
 
  /**
   * 獲取ftp目錄下的所有文件
   * @param dir
   * @return
   */
  public ftpfile[] getfiles(string dir) throws exception {
    getftpclient();
    ftpfile[] files = new ftpfile[0];
    try {
      files = ftpclient.listfiles(dir);
    }catch (throwable thr){
      thr.printstacktrace();
    }
    return files;
  }
 
  /**
   * 獲取ftp目錄下的某種類型的文件
   * @param dir
   * @param filter
   * @return
   */
  public ftpfile[] getfiles(string dir, ftpfilefilter filter) throws exception {
    getftpclient();
    ftpfile[] files = new ftpfile[0];
    try {
      files = ftpclient.listfiles(dir, filter);
    }catch (throwable thr){
      thr.printstacktrace();
    }
    return files;
  }
 
  /**
   * 創(chuàng)建文件夾
   * @param remotedir
   * @return 如果已經(jīng)有這個文件夾返回false
   */
  public boolean makedirectory(string remotedir) throws exception {
    getftpclient();
    boolean result = false;
    try {
      result = ftpclient.makedirectory(remotedir);
    } catch (ioexception e) {
      e.printstacktrace();
    }
    return result;
  }
 
  public boolean mkdirs(string dir) throws exception {
    boolean result = false;
    if (null == dir) {
      return result;
    }
    getftpclient();
    ftpclient.changeworkingdirectory("/");
    stringtokenizer dirs = new stringtokenizer(dir, "/");
    string temp = null;
    while (dirs.hasmoreelements()) {
      temp = dirs.nextelement().tostring();
      //創(chuàng)建目錄
      ftpclient.makedirectory(temp);
      //進入目錄
      ftpclient.changeworkingdirectory(temp);
      result = true;
    }
    ftpclient.changeworkingdirectory("/");
    return result;
  }
}

創(chuàng)建ftpclienttest.java測試類

上傳一張圖片到ftp服務器,并將文件重新命名為hrabbit.jpg,代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
 * ftpclient測試
 * @auther: hrabbit
 * @date: 2018-12-21 9:14 pm
 * @description:
 */
@runwith(springrunner.class)
@springboottest
public class ftpclienttest {
 
  /**
   * 測試上傳
   */
  @test
  public void uploadfile(){
    boolean flag = ftputils.uploadfile("hrabbit.jpg", "/users/mrotaku/downloads/klklklkl_4x.jpg");
    assert.assertequals(true, flag);
  }
 
}

程序完美運行,這時候我們查看我們的ftp服務器,http://localhost:8866/hrabbit.jpg

Spring Boot整合FTPClient線程池的實現(xiàn)示例

碼云地址:https://gitee.com/hrabbit/hrabbit-admin

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:https://www.jianshu.com/p/6270b2308c4e

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 色小孩导航| 亚洲sss综合天堂久久久 | 99精品久久精品一区二区 | 亚洲国产精品成人午夜在线观看 | 成人久久伊人精品伊人 | 无人在线视频高清免费观看动漫 | 美女张开下身让男人桶 | 逼里逼里香 | 白丝女仆被啪到深夜漫画 | 久久机热免费视频 | 欧美特黄视频在线观看 | 日韩毛片基地一区二区三区 | 波多野结衣在线中文字幕 | 国产偷窥女洗浴在线观看亚洲 | 糖心vlog麻豆精东影业传媒 | 色久网 | 久久亚洲精品成人 | 99精品免费在线观看 | 久久er99热精品一区二区 | 午夜办公室在线观看高清电影 | 无人区在线观看免费视频国语 | av魔镜收集号 | 丝袜高跟小说 | 国产黄频 | 国产青青操| 欧美日韩亚洲第一区在线 | 男人操女人免费视频 | www.av免费| 精品久久久久国产免费 | 高清毛片一区二区三区 | 免费大秀视频在线播放 | 国产永久免费视频m3u8 | 91制片厂制作传媒网站破解 | 精品国产一区二区三区久久久蜜臀 | 四大美女思春艳史片 | 火影忍者羞羞 | 99影视在线视频免费观看 | 97综合| 久久中文字幕免费高清 | 9420高清视频在线观看网百度 | 国产性视频 |