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服务器的更多相关文章

  1. 剑指架构师系列-持续集成之Maven+Nexus+Jenkins+git+Spring boot

    1.Nexus与Maven 先说一下这个Maven是什么呢?大家都知道,Java社区发展的非常强大,封装各种功能的Jar包满天飞,那么如何才能方便的引入我们项目,为我所用呢?答案就是Maven,只需要 ...

  2. 剑指架构师系列-spring boot的logback日志记录

    Spring Boot集成了Logback日志系统. Logback的核心对象主要有3个:Logger.Appender.Layout 1.Logback Logger:日志的记录器 主要用于存放日志 ...

  3. 剑指架构师系列-Linux下的调优

    1.I/O调优 CentOS下的iostat命令输出如下: $iostat -d -k 1 2 # 查看TPS和吞吐量 参数 -d 表示,显示设备(磁盘)使用状态:-k某些使用block为单位的列强制 ...

  4. 剑指架构师系列-MySQL调优

    介绍MySQL的调优手段,主要包括慢日志查询分析与Explain查询分析SQL执行计划 1.MySQL优化 1.慢日志查询分析 首先需要对慢日志进行一些设置,如下: SHOW VARIABLES LI ...

  5. 剑指架构师系列-Nginx的安装与使用

    Nginx可以干许多事情,在这里我们主要使用Nginx的反向代理与负载均衡功能. 1.Nginx的下载安装 在安装Nginx前需要安装如下软件: GCC  Nginx是C写的,需要用GCC编译 PCR ...

  6. 剑指架构师系列-Redis集群部署

    初步搭建Redis集群 克隆已经安装Redis的虚拟机,我们使用这两个虚拟机中的Redis来搭建集群. master:192.168.2.129 端口:7001 slave:192.168.2.132 ...

  7. 剑指架构师系列-tomcat6通过IO复用实现connector

    由于tomcat6的配置文件如下: <Connector port="80" protocol="org.apache.coyote.http11.Http11Ni ...

  8. 剑指架构师系列-Struts2构造函数的循环依赖注入

    Struts2可以完成构造函数的循环依赖注入,来看看Struts2的大师们是怎么做到的吧! 首先定义IBlood与BloodImpl类: public interface IBlood { } pub ...

  9. 剑指架构师系列-tomcat6通过伪异步实现connector

    首先在StandardService中start接收请求的线程,如下: synchronized (connectors) { for (int i = 0; i < connectors.le ...

随机推荐

  1. leetcode算法: Keyboard Row

    Given a List of words, return the words that can be typed using letters of alphabet on only one row' ...

  2. Java 局部变量、实例变量、类变量(静态变量)区别

    1. 局部变量: 局部变量是类的方法中的变量: 2. 实例变量: 实例变量也是类中独立于方法之外的变量,不过没有static修饰,也叫 对象变量 3. 类变量(静态变量): 类变量是类中独立于方法之外 ...

  3. 树莓派(1)- Raspberry Pi 3B 安装系统并联网

    一.背景 昨天到手淘宝买的3B,既然买了就不能让它吃灰,动起来. 二.物料 名称 说明 硬件  树莓派3B 主体 树莓派电源 5V 2A sd卡 4G低速(推荐是16G class10),我手头只有这 ...

  4. 如何对url的的参数进行一个对象转化

    本例子是直接写在一个react组件中的 不过方法还是原生的方法 不多说 直接上代码 比如我们有一个 url: 'www.zhangfeng.com?id=1&name=zhangfeng&am ...

  5. 数据结构-快速排序(C#实现)

    快速排序的主要思路: 1.在数组首尾处各设一个标记 2.取出数组第一个值作为中枢值 3.所有数据跟中枢值比较:比中枢值小的放中枢值左边,首部标记++往右推一位,大的放中枢值右边,尾部标记--往左推一位 ...

  6. laravel整合JWT遇到的问题及解决方案

    1.在执行 php artisan jwt:secret 生成密钥的时候,报错Method Tymon\JWTAuth\Commands\JWTGenerateCommand::handle() do ...

  7. 【webstorm使用手册】如何让webstorm支持nextcss基础语法?

    第一步, 安装 PostCss插件 如果不知道如何安装插件,参看:http://www.cnblogs.com/codelovers/p/7048113.html 第二步,设置文件类型解析方式 打开F ...

  8. [HNOI 2014]世界树

    Description 题库链接 给出一棵 \(n\) 个节点的树, \(q\) 次询问,每次给出 \(k\) 个关键点.树上所有的点会被最靠近的关键点管辖,若距离相等则选编号最小的那个.求每个关键点 ...

  9. [SDOI2017]序列计数

    题目描述 Alice想要得到一个长度为nn的序列,序列中的数都是不超过mm的正整数,而且这nn个数的和是pp的倍数. Alice还希望,这nn个数中,至少有一个数是质数. Alice想知道,有多少个序 ...

  10. [SDOI2010]古代猪文

    题目背景 “在那山的那边海的那边有一群小肥猪.他们活泼又聪明,他们调皮又灵敏.他们自由自在生活在那绿色的大草坪,他们善良勇敢相互都关心……” ——选自猪王国民歌 很久很久以前,在山的那边海的那边的某片 ...