剑指架构师系列-ftp服务器

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指架构师系列-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实现项目的编译发布和部署

剑指架构师系列-MySQL调优

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

剑指架构师系列-ActiveMQ队列的使用

剑指架构师系列-Struts2的缓存

剑指架构师系列-Redis安装与使用