我的情况是利用宝塔面板,将新建FTP 和 本地文件链接
一.上传
1. 新建上传目录
在根目录下,新建/www/upload/
,作为上传目标地址
2. 新建FTP
其中
- 根目录要指定之前建立的目录
- TCP控制连接端口21,默认的协议端口,
- 20:主动模式数据端口
- 39000~40000:被动模端口范围
这几个端口需要在防火墙中放行,
使用命令firewall-cmd --zone=public --add-port=20/tcp --permanent
开启端口
查看已打开的端口:firewall-cmd --list-ports
3. Java实现
Maven依赖添加
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.3</version>
</dependency>
然后在文件上传工具类中添加功能实现代码
public String upload(MultipartFile uploadFile) {
//创建客户端对象
FTPClient ftp = new FTPClient();
//文件输出流
InputStream inputStream=null;
try {
//ip+端口=连接ftp服务器
ftp.connect("xx.xx.xx.xx",21);
//登录:输入新增FTP时设置的用户名和密码
ftp.login("admin","admin");
//上传路径
String path = "/www/upload/";
//检测该路径是否存在,若不存在便新建此路径
boolean b = ftp.changeWorkingDirectory(path);
if(!b) {
ftp.makeDirectory(path);
}
//制定上传路径
ftp.changeWorkingDirectory(path);
//指定上传文件的类型为二进制文件
ftp.setFileType(FTP.BINARY_FILE_TYPE);
//获取文件输入流
inputStream= uploadFile.getInputStream();
//得到源文件名
String oldName = uploadFile.getOriginalFilename();
//利用时间戳生成新的文件名
String filename = String.valueOf(new Date().getTime()) + oldName.substring(oldName.lastIndexOf("."));
//上传
ftp.storeFile(filename,inputStream);
//返回文件名
return filename;
} catch (SocketException e) {
System.out.println(e.getMessage());
e.printStackTrace();
} catch (IOException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}finally {
try {
//关闭文件流
inputStream.close();
//退出
ftp.logout();
//断开连接
ftp.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
return "没有么";
}
页面中可以这样
<form action="Controller访问路径" id="combined_tasks_form" method="post" enctype="multipart/form-data">
<input type="file" name="file"/>
<input type="submit" value="上传"/>
</form>
//必须设置属性enctype="multipart/form-data"
OK,经过上面这几步操作,我们就可以成功的将文件上传到服务器的/www/upolad
文件下了。
若是不成功,可以看看上传目标文件夹是否有读写权限。查看upload文件夹的权限
改为可写入即可。
二、访问上传后的文件
1.通过ftp直接下载
FTP是文件传输协议,我们再次通过访问该ftp路径,即可下载服务器中的文件
例如:ftp://admin:admin@xx.xx.xx.xx/index.html
就可以下载此html文档了。
通过http请求仅查看
查看的话,就要将磁盘路径映射到网络地址,所以我们可以新建一个网站站点
在这里新建一个站点,
- 域名:如果没有域名,可以填写ip
- 根目录:要映射到之前上传文件的目录,如我的:
/www/upload
- 端口默认为80,所以要打开80口的防火墙访问
都做好后,就可以通过http://xx.xx.xx.xx:80/index.html
访问资源了。
更新
通过上面的工作,localhost本地运行是没有问题的。
如果将项目部署到服务器,会出现无法上传的问题。
解决方法
再文件传送前面添加
ftp.enterLocalPassiveMode();
ftp.storeFile(filename,local);
原因:
根据数据连接是否是服务器端主动建立,FTP有主动和被动两种模式
- 主动模式:服务器端主动建立数据连接,其中服务器端的端口号为 20,客户端的端口号随机,但是必须大于 1024,因为 0~1023 是熟知端口号
- 被动模式:客户端主动建立数据连接,其中客户端的端口号由客户端自己指定,服务器端的端口号随机
所以当客户端主动建立连接,服务器的端口号随机,这个随机的端口号可能并没有被开启,造成连接失败,上传失败。