剑指架构师系列-ftp服务器
1、安装FTP
我们在开发项目时,肯定需要专门的一台ftp服务器来存在上传的静态资源,今天我们就在CentOS下搭建一个ftp服务器。
1.安装vsftpd组件,安装完后,有/etc/vsftpd/vsftpd.conf 文件,用来配置,还有新建了一个ftp用户和ftp的组,指向home目录为/var/ftp,默认是nologin(不能登录系统)
yum -y install vsftpd
可以用下面命令查看用户
cat /etc/passwd
默认ftp服务是没有启动的,用下面命令启动
/bin/systemctl start vsftpd.service
2.安装ftp客户端组件(用来验证是否vsftpd)
yum -y install ftp
执行命令尝试登录
ftp localhost
输入用户名ftp,密码随便(因为默认是允许匿名的)
登录成功,就代表ftp服务可用了。但是,外网是访问不了的,所以还要继续配置。
3.取消匿名登陆
vi /etc/vsftpd/vsftpd.conf
把第一行的 anonymous_enable=YES ,改为NO
重启
/bin/systemctl restart vsftpd.service
4.新建一个用户(ftpuser为用户名,随便就可以)
useradd ftpuser
修改密码
passwd ftpuser
这样一个用户建完,可以用这个登录,记得用普通登录不要用匿名了。登录后默认的路径为 /home/ftpuser
5.开放21端口
因为ftp默认的端口为21,而Centos默认是没有开启的,所以要修改iptables文件
vi /etc/sysconfig/iptables
在行上面有22 -j ACCEPT 下面另起一行输入跟那行差不多的,只是把22换成21,然后:wq保存。
还要运行下,重启iptables
/bin/systemctl restart iptables.service
外网是可以访问上去了,可是发现没法返回目录,也上传不了,因为selinux作怪了。
6.修改selinux
getsebool -a | grep ftp
执行上面命令,再返回的结果看到两行都是off,代表,没有开启外网的访问
.... allow_ftpd_full_access off .... .... ftp_home_dir off
只要把上面都变成on就行
执行
setsebool -P allow_ftpd_full_access 1 setsebool -P ftp_home_dir off 1
再重启一下vsftpd。
2、使用apache ftp client操作资源服务器
<!-- ftp client --> <dependency> <groupId>commons-net</groupId> <artifactId>commons-net</artifactId> <version>3.4</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-juli</artifactId> </exclusion> </exclusions> </dependency>
除了引入ftp client包外,还需要引入spring-boot-starter-web,这样就可以做为一个单独的应用启动了。
在src/test/java目录下新建Test01.java文件,测试对FTP资源文件的基本操作,包括连接,上传、下载和删除等。
public class Test02 {
private static FTPClient ftpClient = null;
private static FTPClientConfig getFtpConfig() {
FTPClientConfig ftpConfig = new FTPClientConfig(FTPClientConfig.SYST_UNIX);
ftpConfig.setServerLanguageCode(FTP.DEFAULT_CONTROL_ENCODING);
return ftpConfig;
}
public static boolean connectServer() {
boolean flag = true;
if (ftpClient == null) {
int reply;
try {
ftpClient = new FTPClient();
ftpClient.setControlEncoding("GBK");
ftpClient.configure(getFtpConfig());
ftpClient.connect("192.168.2.129");
ftpClient.login("ftpuser", "ftpuser");
ftpClient.setDefaultPort(21);
reply = ftpClient.getReplyCode();
ftpClient.setDataTimeout(120000);
if (!FTPReply.isPositiveCompletion(reply)) {
ftpClient.disconnect();
flag = false;
}
} catch (SocketException e) {
flag = false;
e.printStackTrace();
} catch (IOException e) {
flag = false;
e.printStackTrace();
}
}
return flag;
}
/**
* 功能说明:获取工作区
*/
public static String getWorkingDirectory(File localFile, File rootFile) {
String localDir = localFile.getAbsoluteFile().toURI().toString();
String root = rootFile.getAbsoluteFile().toURI().toString();
if (localDir.length() <= root.length()) {
return "/";
} else {
return "/" + localDir.substring(root.length());
}
}
/**
* 上传单个文件,并重命名
*/
public static boolean uploadFile(File localFile,String newFileName,final String distFolder) {
boolean flag = true;
try {
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
/*
* 每次数据连接之前,ftp client告诉ftp server开通一个端口来传输数据。为什么要这样做呢,
* 因为ftp server可能每次开启不同的端口来传输数据,但是在linux上或者其他服务器上面,由于安全限制,可能某些端口没有开启
*/
ftpClient.enterLocalPassiveMode();
ftpClient.setFileTransferMode(FTP.STREAM_TRANSFER_MODE);
InputStream input = new FileInputStream(localFile);
ftpClient.changeWorkingDirectory(distFolder);
flag = ftpClient.storeFile(newFileName, input);
if (flag) {
System.out.println("upload file success:" + localFile.getName());
} else {
System.out.println("upload file filed:" + localFile.getName());
}
input.close();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return flag;
}
/**
* 列出服务器上文件和目录
* @param regStr--匹配的正则表达式
* @throws IOException
*/
public static void listRemoteFiles(String regStr) throws IOException {
try {
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
ftpClient.enterLocalPassiveMode();
ftpClient.setFileTransferMode(FTP.STREAM_TRANSFER_MODE);
FTPFile files[] = ftpClient.listFiles(regStr);
if (files == null || files.length == 0)
System.out.println("没有任何文件!");
else {
for (int i = 0; i < files.length; i++) {
System.out.println(files[i].getName()+" "+files[i].getTimestamp().getTime()+" "+files[i].isDirectory()+" "+files[i].getSize()/1024+"k");
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 功能说明:从ftp上下载文件到本地
*/
public static boolean loadFile(String remoteFileName, String localFileName) {
boolean flag = true;
connectServer();
// 下载文件
BufferedOutputStream buffOut = null;
try {
buffOut = new BufferedOutputStream(new FileOutputStream(localFileName));
flag = ftpClient.retrieveFile(remoteFileName, buffOut);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (buffOut != null)
buffOut.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return flag;
}
/**
* 删除ftp中的文件
*/
public static boolean deleteFile(String pathname) {
try {
return ftpClient.deleteFile(pathname);
} catch (IOException e) {
return false;
}
}
public static void main(String[] args) throws IOException {
boolean flag = new Test02().connectServer();
System.out.println("是否连接成功?"+flag);
uploadFile(new File("C:/1.png"),"ddd.png", "upload");
// String workDir = ftpClient.printWorkingDirectory();
// System.out.println(workDir);
// listRemoteFiles("*");
// deleteFile("/home/ftpuser/images/bb.png");
// loadFile("/home/ftpuser/images/1459584546868_aabb.jpg","C://dd.png");
}
}
3、访问资源文件
@SpringBootApplication
public class Application extends WebMvcConfigurerAdapter{
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
// 要调用这个方法必须要继承类:WebMvcConfigurerAdapter
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("file:upload/");
}
}
注意这个类一定要继承WebMvcConfigurerAdapter类并且要写上你的addResourceHandlers()方法。
不要忘记引入application.yml文件!!
pom.xml文件在<project>节点下加入如下内容。
<build> <resources> <resource> <directory>src/main/resources</directory> </resource> </resources> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build> <profiles> <profile> <id>jdk-1.6</id> <activation> <activeByDefault>true</activeByDefault> <jdk>1.6</jdk> </activation> <properties> <maven.compiler.source>1.6</maven.compiler.source> <maven.compiler.target>1.6</maven.compiler.target> <maven.compiler.compilerVersion>1.6</maven.compiler.compilerVersion> </properties> </profile> </profiles>
然后用Maven Install一下,在target目录中得到mazhi-core-0.0.1-SNAPSHOT.jar文件,上传到与upload目录同级的目录下,通过如下的命令启动这个jar。
java -jar mazhi-core-0.0.1-SNAPSHOT.jar
启动成功后,就可以在windows中通过浏览器进行图片的访问了,访问地址如下:
http://192.168.2.129:8081/static/bb.png
图片在浏览器里显示出来,表示访问成功。

剑指架构师系列-ftp服务器的更多相关文章
- 剑指架构师系列-持续集成之Maven+Nexus+Jenkins+git+Spring boot
1.Nexus与Maven 先说一下这个Maven是什么呢?大家都知道,Java社区发展的非常强大,封装各种功能的Jar包满天飞,那么如何才能方便的引入我们项目,为我所用呢?答案就是Maven,只需要 ...
- 剑指架构师系列-spring boot的logback日志记录
Spring Boot集成了Logback日志系统. Logback的核心对象主要有3个:Logger.Appender.Layout 1.Logback Logger:日志的记录器 主要用于存放日志 ...
- 剑指架构师系列-Linux下的调优
1.I/O调优 CentOS下的iostat命令输出如下: $iostat -d -k 1 2 # 查看TPS和吞吐量 参数 -d 表示,显示设备(磁盘)使用状态:-k某些使用block为单位的列强制 ...
- 剑指架构师系列-MySQL调优
介绍MySQL的调优手段,主要包括慢日志查询分析与Explain查询分析SQL执行计划 1.MySQL优化 1.慢日志查询分析 首先需要对慢日志进行一些设置,如下: SHOW VARIABLES LI ...
- 剑指架构师系列-Nginx的安装与使用
Nginx可以干许多事情,在这里我们主要使用Nginx的反向代理与负载均衡功能. 1.Nginx的下载安装 在安装Nginx前需要安装如下软件: GCC Nginx是C写的,需要用GCC编译 PCR ...
- 剑指架构师系列-Redis集群部署
初步搭建Redis集群 克隆已经安装Redis的虚拟机,我们使用这两个虚拟机中的Redis来搭建集群. master:192.168.2.129 端口:7001 slave:192.168.2.132 ...
- 剑指架构师系列-tomcat6通过IO复用实现connector
由于tomcat6的配置文件如下: <Connector port="80" protocol="org.apache.coyote.http11.Http11Ni ...
- 剑指架构师系列-Struts2构造函数的循环依赖注入
Struts2可以完成构造函数的循环依赖注入,来看看Struts2的大师们是怎么做到的吧! 首先定义IBlood与BloodImpl类: public interface IBlood { } pub ...
- 剑指架构师系列-tomcat6通过伪异步实现connector
首先在StandardService中start接收请求的线程,如下: synchronized (connectors) { for (int i = 0; i < connectors.le ...
随机推荐
- Python学习之输入输出、数据类型
#coding=utf-8 # 输入 print'100+200=',100+200 # 输入 # name = raw_input('tell me your name:') # print'hel ...
- 使用TortoiseSVN打Tag
参考了 https://blog.csdn.net/liuzx32/article/details/9123401. 值得注意的点是: 选择路径的时候,不要先点进去自己建好叶子节点路径再选择该路径,会 ...
- 高级控件之Scrollview ( 滑动屏幕 ) 与 Imageview (滑动屏幕 切换图片)
ScrollView 的xml布局 <?xml version="1.0" encoding="utf-8"?> <RelativeLayo ...
- window7下配置python2.7+tornado3.3开发环境
发现之前写太繁琐..这里分享下同学的方法 1,安装 Python 2.7.x 版本地址:https://www.python.org/downloads/release/python-278/2,安装 ...
- oracle批量插入优化方案
今天听DBA说如果从一个表批量查询出一批数据之后批量插入另外一张表的优化方案: 1)不写归档日志: 2)采用独占 关于insert /*+ append */我们需要注意以下三点: a.非归档模式下, ...
- Paper藐小之处明察秋毫故时有物外之趣
暂且针对第一篇叶脉提取的paper 插入图像的"图 N": 英 Times New Roman, 中 宋体, 10磅. 文末的引文: 两端对齐. 流程图框格内文字换行时, 忌: 将 ...
- vue-cli 体验
vue-cli 是一个官方发布 vue.js 项目脚手架,使用 vue-cli 可以快速创建 vue 项目,GitHub地址是:https://github.com/vuejs/vue-cli 一. ...
- [HEOI2016]排序
题目描述 在2016年,佳媛姐姐喜欢上了数字序列.因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题,需要你来帮助他.这个难题是这样子 的:给出一个1到n的全排列,现在对这个全排列序列进 ...
- 计蒜客NOIP模拟赛(2)D1T3 深黑幻想
[问题描述] 凡终于发愤图强,决定专心搞OI,不再玩纸牌和坑钱了!没过多久就飘飘然了,总是陷入自己进了集训队的深黑幻想之中. 样听说了之后,决定考一考凡欧拉回路怎么写.样:“我给你出一道题 ...
- 删数方案数(regex)
[题目描述] 给出一个正整数序列 a,长度为 n,cyb 不喜欢完美,他要删掉一些数(也可以不删,即删掉0个),但是他不会乱删,他希望删去以后,能将 a 分成 2 个集合,使得两个非空集合的数的和相同 ...