您的位置:首页 > 理论基础 > 计算机网络

ftpClient ,httpClient

2016-06-23 08:47 330 查看
 最近项目需要实现FTP上传、下载功能以及http接口,采用了Apache Commons Net API。代码很快就完成了,但由于对相关API使用场景不是很熟悉,走了一些弯路,抽一点时间做一下总结。

 出现过FTP response 421 received.Server closed connection 异常,原因是

加了ftpClient.enterLocalPassiveMode()配置,去掉这句配置后就可以。

         A主动被动模式选择:FTP主动模式和被动模式的详细介绍可以参考(http://blog.csdn.net/huanggang028/article/details/41248663)。大概意思就是主动模式是客户端向服务端发送PORT命令,然后服务端通过20数据端口连接客户端开启的端口,然后发送数据;被动模式是客户端向服务端发送PASV命令,服务端随机开启一个端口并通知客户端,客户端根据该端口与服务端建立连接,然后发送数据。服务端是两种模式的,使用哪种模式取决于客户端,同时关键点在于网络环境适合用哪种模式,比如客户端在防火墙内,则最好选择被动模式。ftpClient.enterLocalActiveMode()便是配置成主动模式,而ftpClient.enterLocalPassiveMode()则配置成被动模式。
        B文件格式选择:默认是类型是ASCII(普通文本文件),但是为了使得支持任何类型,建议设置成BINARY_FILE_TYPE,并且是在上传和下载操作开始前调用setFileType(int fileType)。
       C上传、下载重载方法的使用选择:比如上传,boolean storeFile(String remote, InputStream local)和OutputStream storeFileStream(String remote),差别是第一个方法如果我们不用关心到底已经从InputStream中传递了多少字节,完全依靠接口内部实现完成输入输出操作,而第二个方法使得我们可以在上传过程中控制传送字节速度等额外操作,比如传送进度的实现便可以依赖此方法。但是,需要注意的是,如果采用了第二个方法来做, 必须靠我们去实现是否上传完毕、下载完毕的事后控制,否则会出现问题。比如我们采用第二个方法,需要手动关闭流,同时,紧接着调用completePendingCommand()方法。如果使用第一个方法不能调用completePendingCommand()方法,因为它一旦被调用, 会一直等待FTP服务器返回226Transfer complete,但是FTP服务器只有在接受流执行close方法时,才会返回。不该调用的时候调用了便会出现僵死现象,同时报错:
[java] view plain copy
 






<span style="font-size:18px;">    14/11/19 13:43:29 ERROR expand.FTPSupport: FTP response 421 received.  Server closed connection.  

org.apache.commons.net.ftp.FTPConnectionClosedException: FTP response 421 received.  Server closed connection.  

at org.apache.commons.net.ftp.FTP.__getReply(FTP.java:363)  

at org.apache.commons.net.ftp.FTP.__getReply(FTP.java:290)  

at org.apache.commons.net.ftp.FTP.getReply(FTP.java:637)  

at org.apache.commons.net.ftp.FTPClient.completePendingCommand(FTPClient.java:1637)</span>  

在上传下载的过程中,上传时采用的是
String jsondata = JSONArray.fromObject(datas).toString();

InputStream in = new ByteArrayInputStream(jsondata.getBytes("UTF-8"));

ftpclient.storeFile(filename, in)

在下载文件的时候是通过字符流来操作的

InputStream in = ftpclient.retrieveFileStream(file.getName())

BufferedReader reader = new BufferedReader(new InputStreamStreamReader(in))

reader.readline();

 
测试的时候,发现在本地没有问题,上到正式机以后,发现reader.readline()读出来的数据解码有问题。
在httpclient操作中,也存在这样的问题。
需要修改流出来方式,上传的时候采用字节流方式,下载的时候也需要采用字节流处理。

 同时自己通过判断in.read()!=-1作为文件结束,存在有时不同操作系统结束符有问题,
然后采用Apache common的IOUitls类解决。

 
IOUtils.toByteArray(InputStream in)可以将字符流转换成byte数组。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: