Giter VIP home page Giter VIP logo

hutool's Introduction

🍬A set of tools that keep Java sweet.

👉 https://hutool.cn/ 👈

star github star




🌎English Documentation


📚简介

Hutool是一个功能丰富且易用的Java工具库,通过诸多实用工具类的使用,旨在帮助开发者快速、便捷地完成各类开发任务。 这些封装的工具涵盖了字符串、数字、集合、编码、日期、文件、IO、加密、数据库JDBC、JSON、HTTP客户端等一系列操作, 可以满足各种不同的开发需求。

🎁Hutool名称的由来

Hutool = Hu + tool,是原公司项目底层代码剥离后的开源库,“Hu”是公司名称的表示,tool表示工具。Hutool谐音“糊涂”,一方面简洁易懂,一方面寓意“难得糊涂”。

🍺Hutool理念

Hutool既是一个工具集,也是一个知识库,我们从不自诩代码原创,大多数工具类都是搬运而来,因此:

  • 你可以引入使用,也可以拷贝和修改使用,而不必标注任何信息,只是希望能把bug及时反馈回来。
  • 我们努力健全中文注释,为源码学习者提供良好地学习环境,争取做到人人都能看得懂。

🛠️包含组件

一个Java基础工具类,对文件、流、加密解密、转码、正则、线程、XML等JDK方法进行封装,组成各种Util工具类,同时提供以下组件:

模块 介绍
hutool-aop JDK动态代理封装,提供非IOC下的切面支持
hutool-bloomFilter 布隆过滤,提供一些Hash算法的布隆过滤
hutool-cache 简单缓存实现
hutool-core 核心,包括Bean操作、日期、各种Util等
hutool-cron 定时任务模块,提供类Crontab表达式的定时任务
hutool-crypto 加密解密模块,提供对称、非对称和摘要算法封装
hutool-db JDBC封装后的数据操作,基于ActiveRecord**
hutool-dfa 基于DFA模型的多关键字查找
hutool-extra 扩展模块,对第三方封装(模板引擎、邮件、Servlet、二维码、Emoji、FTP、分词等)
hutool-http 基于HttpUrlConnection的Http客户端封装
hutool-log 自动识别日志实现的日志门面
hutool-script 脚本执行封装,例如Javascript
hutool-setting 功能更强大的Setting配置文件和Properties封装
hutool-system 系统参数调用封装(JVM信息等)
hutool-json JSON实现
hutool-captcha 图片验证码实现
hutool-poi 针对POI中Excel和Word的封装
hutool-socket 基于Java的NIO和AIO的Socket封装
hutool-jwt JSON Web Token (JWT)封装实现

可以根据需求对每个模块单独引入,也可以通过引入hutool-all方式引入所有模块。


📝文档

📘中文文档

📘中文备用文档

📙参考API

🎬视频介绍


🪙支持Hutool

💳捐赠

如果你觉得Hutool不错,可以捐赠请维护者吃包辣条~,在此表示感谢^_^。

Gitee上捐赠

👕周边商店

你也可以通过购买Hutool的周边商品来支持Hutool维护哦!

我们提供了印有Hutool Logo的周边商品,欢迎点击购买支持:

👉 Hutool 周边商店 👈


📦安装

🍊Maven

在项目的pom.xml的dependencies中加入以下内容:

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.27</version>
</dependency>

🍐Gradle

implementation 'cn.hutool:hutool-all:5.8.27'

📥下载jar

点击以下链接,下载hutool-all-X.X.X.jar即可:

🔔️注意 Hutool 5.x支持JDK8+,对Android平台没有测试,不能保证所有工具类或工具方法可用。 如果你的项目使用JDK7,请使用Hutool 4.x版本(不再更新)

🚽编译安装

访问Hutool的Gitee主页:https://gitee.com/dromara/hutool 下载整个项目源码(v5-master或v5-dev分支都可)然后进入Hutool项目目录执行:

./hutool.sh install

然后就可以使用Maven引入了。


🏗️添砖加瓦

🎋分支说明

Hutool的源码分为两个分支,功能如下:

分支 作用
v5-master 主分支,release版本使用的分支,与**库提交的jar一致,不接收任何pr或修改
v5-dev 开发分支,默认为下个版本的SNAPSHOT版本,接受修改或pr

🐞提供bug反馈或建议

提交问题反馈请说明正在使用的JDK版本呢、Hutool版本和相关依赖库版本。

🧬贡献代码的步骤

  1. 在Gitee或者Github上fork项目到自己的repo
  2. 把fork过去的项目也就是你的项目clone到你的本地
  3. 修改代码(记得一定要修改v5-dev分支)
  4. commit后push到自己的库(v5-dev分支)
  5. 登录Gitee或Github在你首页可以看到一个 pull request 按钮,点击它,填写一些说明信息,然后提交即可。
  6. 等待维护者合并

📐PR遵照的原则

Hutool欢迎任何人为Hutool添砖加瓦,贡献代码,不过维护者是一个强迫症患者,为了照顾病人,需要提交的pr(pull request)符合一些规范,规范如下:

  1. 注释完备,尤其每个新增的方法应按照Java文档规范标明方法说明、参数说明、返回值说明等信息,必要时请添加单元测试,如果愿意,也可以加上你的大名。
  2. Hutool的缩进按照Eclipse(不要跟我说IDEA多好用,维护者非常懒,学不会,IDEA真香,改了Eclipse快捷键后舒服多了)默认(tab)缩进,所以请遵守(不要和我争执空格与tab的问题,这是一个病人的习惯)。
  3. 新加的方法不要使用第三方库的方法,Hutool遵循无依赖原则(除非在extra模块中加方法工具)。
  4. 请pull request到v5-dev分支。Hutool在5.x版本后使用了新的分支:v5-master是主分支,表示已经发布**库的版本,这个分支不允许pr,也不允许修改。
  5. 我们如果关闭了你的issue或pr,请不要诧异,这是我们保持问题处理整洁的一种方式,你依旧可以继续讨论,当有讨论结果时我们会重新打开。

📖文档源码地址

文档源码地址 点击前往添砖加瓦


⭐Star Hutool

Stargazers over time

hutool's People

Contributors

bwcx-jzy avatar cal101 avatar createsequence avatar dahuoyzs avatar dazer007 avatar easepan avatar echohlne avatar fengbaoheng avatar fulabula avatar handy-git avatar hellozrh avatar hsoftxl avatar husky-jzq avatar hzdjulytech avatar lfm avatar looly avatar lzpeng723 avatar meimingle avatar micuncang avatar mr-po avatar samho2008 avatar shadow-li0327 avatar shenshaoming avatar singuj avatar ted-engineer avatar totalo avatar uyong avatar vampireachao avatar wangliang181230 avatar zemochen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hutool's Issues

HttpConnection类initConn方法改进

希望该方法里面设置default header时 header(Header.ACCEPT_ENCODING, "gzip", true);这个不要默认设置,不然输出来的数据还需要手工用gzip去解压.
header(Header.CONTENT_TYPE, "application/x-www-form-urlencoded", true); 好像只有post,patch,put 时才有用吧
另外302跳转的支持最好也加上,用一个参数来控制是否跳转

hutool-system包优化修改

hutool-system包下的方法都不是静态的,每次使用都需要new一个对象,感觉使用起来不太方便,能不能改成静态方法, 这样感觉用起来比较顺手,谢谢

BUG 3.0.6版本 FileUtil.copy 方法错误

FileUtil 788行
会错误的把文件也判断成文件夹
FileUtil.internalCopyDir 方法中对于原文件是否为文件夹的的判断有问题

if(src.isDirectory())

src应该改为srcFile

if(srcFile.isDirectory())

HttpUtil发送json请求自动判定contentType的问题

        public static String getContentTypeByRequestBody(String body) {
		String contentType = null;
		if(StrUtil.isNotBlank(body)) {
			char firstChar = body.charAt(0);
			switch (firstChar) {
			case '{':
				//JSON请求体
				contentType = "application/json";
				break;
			case '<':
				//XML请求体
				contentType = "application/xml";
				break;

			default:
				break;
			}
		}
		return contentType;
	}

上述代码中,是通过case '{':是通过判断body是否以‘{’开头来判定是否是json参数请求,忽略了json数组的情况,如:[{},{},{},{}], Java-Controller代码:

 @RequestMapping(value = "testSaveBatch.do", method = RequestMethod.POST)
 @ResponseBody
 public ServerResponse<String> testSaveBatch(@RequestBody List<SaleDetailVo> vos, String userAccount) throws Exception {

 }

。故而,此种情况也应该判定为json参数请求。您这边看下,我描述是否有问题,如果描述正确的话,还请修正下。谢谢。

反序列化问题

json数据如下:
{
"statusCode": 200,
"message": "OK",
"skip": 0,
"limit": 20,
"total": 30,
"data": [
{
"Price": {
"ADT": [
[
{
"BookingCode": [
"N",
"N"
]
}
]
]
}
}
]
}

建立相应的bean

public class ADT {

private List<String> BookingCode;
public void setBookingCode(List<String> BookingCode) {
     this.BookingCode = BookingCode;
 }
 public List<String> getBookingCode() {
     return BookingCode;
 }

}

public class Data {

private Price Price;
public void setPrice(Price Price) {
     this.Price = Price;
 }
 public Price getPrice() {
     return Price;
 }

}

public class JsonRootBean {

private int statusCode;
private String message;
private int skip;
private int limit;
private int total;
private List<Data> data;

public void setStatusCode(int statusCode) {
	this.statusCode = statusCode;
}

public int getStatusCode() {
	return statusCode;
}

public void setMessage(String message) {
	this.message = message;
}

public String getMessage() {
	return message;
}

public void setSkip(int skip) {
	this.skip = skip;
}

public int getSkip() {
	return skip;
}

public void setLimit(int limit) {
	this.limit = limit;
}

public int getLimit() {
	return limit;
}

public void setTotal(int total) {
	this.total = total;
}

public int getTotal() {
	return total;
}

public void setData(List<Data> data) {
	this.data = data;
}

public List<Data> getData() {
	return data;
}

}

public class Price {

private List<List<ADT>> ADT;
public void setADT(List<List<ADT>> ADT) {
     this.ADT = ADT;
 }
 public List<List<ADT>> getADT() {
     return ADT;
 }

}

test:

public static void main(String[] args) {
String json = "{"statusCode":200,"message":"OK","skip":0,"limit":20,"total":30,"data":[{"Price":{"ADT":[[{"BookingCode":["N","N"]}]]}}]}";
JsonRootBean objJsonRootBean = JSONUtil.toBean(json, JsonRootBean.class);
ADT sObject = objJsonRootBean.getData().get(0).getPrice().getADT().get(0).get(0);
System.out.println(sObject.getBookingCode());
}

error:

Exception in thread "main" java.lang.ClassCastException: com.xiaoleilu.hutool.json.JSONObject cannot be cast to sss.ADT
at sss.test.main(test.java:12)

Visual studio error

When I try and follow the windows instructions in the readme I get the following error:

cl.exe /nologo /O2 /EHsc /D "_CRT_SECURE_NO_DEPRECATE" /D "USEOMP" /openmp tsne.obj sptree.obj -Fewindows\bh_tsne.exe
libcpmt.lib(xthrow.obj) : error LNK2038: mismatch detected for '_MSC_VER': value '1900' doesn't match value '1800' in tsne.obj
libucrt.lib(hypot.obj) : error LNK2005: hypot already defined in tsne.obj
windows\bh_tsne.exe : fatal error LNK1169: one or more multiply defined symbols found
NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\x86_amd64\cl.exe"' : return code '0x2'
Stop.

I'm not sure how I can edit the tsne.obj file to adjust this, any advice?

SqlRunner获取tableName为Null

RT,在使用DataSource的时候,用

sqlRunner.find( Entity.create("表名").set("id", "> 30"));

获取的List 里面tableName=null, fieldNames=null 其他的字段有值.

afterException in Apsect.invoke

code sinppets in "Aspcet. invoke"

		try {
			result = ClassUtil.invoke(target, method, args);
		}catch (InvocationTargetException e) {
			afterException(args, method, args, e.getTargetException());
		}catch (Exception e) {
			throw e;//其它异常属于代理的异常,直接抛出
		}

afterException 的第一个参数, 根据上下文, 应该是target嘛, 这里写错了
关于这个afterExecption的使用, 为什么要这样约定呀

FileTypeUtil未关闭流导致文件占用无法删除

今天使用了FileTypeUtil类判断文件类型后,执行删除文件操作,执行失败,原因是文件被占用,发现占用的是java.exe。本来怀疑是自己代码有问题,后来尝试将FileTypeUtil的使用去掉,文件正常删除。
初步判定是FileTypeUtil读取文件后未关闭。

FileTypeUtil文件中,此代码
public static String getType(File file) throws IORuntimeException {
return getType(IoUtil.toStream(file));
}

没有对输入流关闭导致

尝试将代码改成

public static String getType(File file) throws IORuntimeException {
FileInputStream inputStream = IoUtil.toStream(file);
String type = getType(inputStream);
IoUtil.close(inputStream);
return type;
}
后执行,判断后文件不再提示被占用,能够正常删除。

再次感谢分享这么方便的工具。

请求增加数据是否过期校验

如:一条数据,包含创建时间、有效期长短,过期判断。

public static void main(String[] args) {

Date startDate = DateUtil.parseDateTime("2017-09-04 11:52:00");

Date now = DateUtil.parseDateTime("2017-09-04 12:51:00");

System.out.println(isExpired(startDate, now, 1, DateField.HOUR));

}

static boolean isExpired(Date startDate, Date nowDate, Integer timeLength, DateField dateField){

Date endDate = DateUtil.offsiteDate(startDate, dateField, timeLength);

return endDate.before(nowDate);

}

ZIPUtil 解压缩失败

在使用ZIPUtil的时候用了unzip 默认解压方法,系统运行报错 MALFORMED 后来觉得是压缩包里面有中文文件名,然后改成指定编码 ZipUtil.unzip(filePath, Charset.forName("gbk")) ,还是不能正常解压缩,系统运行报错MALFORMED 。
版本号V3.2.2
错误代码如下:
java.lang.IllegalArgumentException: MALFORMED at java.util.zip.ZipCoder.toString(ZipCoder.java:58) at java.util.zip.ZipFile.getZipEntry(ZipFile.java:531)

FileTypeUtil.getType 读取空文件报数组下标越界

File f = new File("G:\\1231\\6666\\tttt\\出错.txt");
try {
     System.out.println("file size= " + f.length());
     System.out.println(FileTypeUtil.getType(f));
} catch (IOException e) {
     e.printStackTrace();
}

//===>
#file size= 0

#java.lang.ArrayIndexOutOfBoundsException

com.xiaoleilu.hutool.util.RuntimeUtil#exec 执行 which 异常

import static com.xiaoleilu.hutool.util.RuntimeUtil.exec;        
final List<String> exec = exec("which java");

异常

Exception in thread "main" com.xiaoleilu.hutool.io.IORuntimeException: IOException: Cannot run program "which java": error=2, No such file or directory
	at com.xiaoleilu.hutool.util.RuntimeUtil.exec(RuntimeUtil.java:32)
	at nio.files.SymbolicLinksDemo.main(SymbolicLinksDemo.java:15)
Caused by: java.io.IOException: Cannot run program "which java": error=2, No such file or directory
	at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
	at com.xiaoleilu.hutool.util.RuntimeUtil.exec(RuntimeUtil.java:30)
	... 1 more
Caused by: java.io.IOException: error=2, No such file or directory
	at java.lang.UNIXProcess.forkAndExec(Native Method)
	at java.lang.UNIXProcess.<init>(UNIXProcess.java:247)
	at java.lang.ProcessImpl.start(ProcessImpl.java:134)
	at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
	... 2 more

关于BloomFilter部分的一些意见

IntMap, LongMap, 求商, 求余可以使用位操作优化, LongMap中add, remove中似乎是存在问题[强转int, 丢失数据], 缺少对于range的校验
BitSetBloomFilter 扩展一点可以增加自定义的HashFunction, 以及使用一些预定义的HashFunction, init的时候 提供类似于LineTokenizer接口, 对于一行数据应该做校验, 提供类似于LineFilter
filter包里面的单个hashFunc的BloomFilter实现似乎是没有太大的意义, hash冲突的可能性太大了
BitMapBloomFilter.add方法对于结果的处理有问题, 还有一些写法层面上的可以改进的地方

Sparse input data

Is there a way to input sparse data? I suspect this is not a straight-forward thing to do, because of the lack of a standard way to store sparse matrices in a text file, i.e. python probably does it different than matlab (did not check though).

使用SqlRunner.FindAll转型失败

使用SqlRunner.FindAll转型失败

List<T> findAll(Entity where, Class<T> beanClass)

转型没报错,但是使用时会提示ClassCaseExcepiton 错误.

AES加解密问题,如何正确创建一个CBC加密模式+填充类型+指定偏移量的AES类

代码实例
//随机生成密钥
byte[] key = SecureUtil.generateKey(SymmetricAlgorithm.AES.getValue()).getEncoded();
AES aes = new AES(Mode.CBC, Padding.NoPadding, key);
aes.setIv(new IvParameterSpec("0102030405060708".getBytes()));
//加密
byte[] encrypt = aes.encrypt(content);

报错如下:

com.xiaoleilu.hutool.crypto.CryptoException: InvalidKeyException: Wrong algorithm: AES or Rijndael required

at com.xiaoleilu.hutool.crypto.symmetric.SymmetricCrypto.encrypt(SymmetricCrypto.java:132)
at com.xiaoleilu.hutool.crypto.symmetric.SymmetricCrypto.encrypt(SymmetricCrypto.java:174)
at com.xu.spider4j.encrypt.SymmetricTest.aesTest3(SymmetricTest.java:92)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

Caused by: java.security.InvalidKeyException: Wrong algorithm: AES or Rijndael required
at com.sun.crypto.provider.AESCrypt.init(AESCrypt.java:83)
at com.sun.crypto.provider.CipherBlockChaining.init(CipherBlockChaining.java:93)
at com.sun.crypto.provider.CipherCore.init(CipherCore.java:591)
at com.sun.crypto.provider.AESCipher.engineInit(AESCipher.java:346)
at javax.crypto.Cipher.implInit(Cipher.java:806)
at javax.crypto.Cipher.chooseProvider(Cipher.java:864)
at javax.crypto.Cipher.init(Cipher.java:1396)
at javax.crypto.Cipher.init(Cipher.java:1327)
at com.xiaoleilu.hutool.crypto.symmetric.SymmetricCrypto.encrypt(SymmetricCrypto.java:128)
... 24 more

hutool使用sax读取excel部分日期显示错误

在使用hutool 3.2.3版本ExcelUtil.read07BySax读取excel时候发现读取日期返回的字符串有问题,格式变成了yyyy-MM-ddHH:mm:ss,而不是yyy-MM-dd HH:mm:ss格式, 部分空单元格未显示为,如图。
2017-12-24_114303

excel内容如下:
2017-12-24_114220

excel见附件。
testExcel.xlsx
谢谢。

关于Log

程序中出现[WARN] Can not find [logging.properties], use [%JRE_HOME%/lib/logging.properties] as default!这行警告,请问这个问题如何解决?

CollectionUtil类的修改建议

CollectionUtil这个类在使用过程中是经常使用的,尤其是newHashMap、newHashSet、newArrayList这几个方法; 在调用这几个方法的时候,需要写"CollectionUtil"这么长的类名,很不方便,如果像guava那样,只用写"Maps.xxx"这样是很方便的. 另外能不能加创建Map时有类似guava的ImmutableMap.of(key, value)方法直接创建键值对

ImageUtil.pressImage()添加图片水印方法,没有释放资源

image

调用 ImageUtil.pressImage() 方法后,执行delete无法删除,报如下错误
2017-09-11 16:40:16
[ERROR]-[Thread: qtp632249781-29]-[com.jfinal.core.ActionHandler.handle()]: /edu/teacher/getLearningCardImage
com.jfinal.render.RenderException: com.xiaoleilu.hutool.io.IORuntimeException: FileSystemException: E:\IdeaCode\AgentAPI\src\main\webapp\temp\fb1facb023054ef99c8a58c0c9733763.png: 另一个程序正在使用此文件,进程无法访问。

在这里qrcodeFile和destFile都是作为临时文件用的,用过之后要删除,但是发现删除不掉

建议增加FTPUtil的构造方法

因为前段时间受病毒影响,一个外部FTP服务器从被动模式修改为主动模式(个人感觉没有用,FTP又用不到445),导致自己负责的项目完全死掉了,后来将项目中的连接模式设为了主动才修复。所以建议新增一个构造方法或者set方法设置连接模式为主动模式
ftpClient.enterLocalActiveMode();//连接模式设为主动模式
ftpClient.setActivePortRange(int,int);//客户端使用端口范围

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.