FTP+反向代理--Day9

一.VSFTPD簡介

1:Linux 的組件(一款軟件),安裝到Linux後通過Java代碼(FtpClient)實現文件上傳.

2:VSFTPD 基於FTP協議

3:爲什麼要使用VSFTPD

3.1:之前實現文件上傳

3.2:使用VSFTPD後優化

       希望在客戶端直接訪問圖片服務器中的圖片,由於VSFTPD是基於FTP協議的,客戶端瀏覽器是需要通過http協議訪問圖片。解決辦法使用Nginx進行反向代理。

二:安裝FTP

1:安裝vsftpd組件

命令:yum -y install vsftpd

2:添加一個ftp用戶

 命令:useradd ftpuser

3:給ftp用戶添加密碼

 passwd ftpuser

4:防火牆開啓21端口

命令:vim /etc/sysconfig/iptables

添加如下:
-A INPUT -m state --state NEW -m tcp -p tcp --dport 21 -j ACCEPT

重啓iptable

命令:CentOS:service iptables restart
命令:CentOS7:/bin/systemctl restart  iptables.service

5:修改selinux(沒開啓就算了)

5.1:查看狀態

命令:getsebool -a | grep ftp 

顯示如下:
ftpd_anon_write --> off
ftpd_connect_all_unreserved --> off
ftpd_connect_db --> off
ftpd_full_access --> off
ftpd_use_cifs --> off
ftpd_use_fusefs --> off
ftpd_use_nfs --> off
ftpd_use_passive_mode --> off
httpd_can_connect_ftp --> off
httpd_enable_ftp_server --> off
tftp_anon_write --> off
tftp_home_dir --> off

5.2:開啓外網訪問

命令:setsebool -P allow_ftpd_full_access on
命令:setsebool -P tftp_home_dir on

6:關閉匿名訪問

命令:vim /etc/vsftpd/vsftpd.conf

7:開啓被動模式

默認是開啓的,但是要指定一個端口範圍,打開vsftpd.conf文件,在後面加上

pasv_min_port=30000
pasv_max_port=30999

8:重啓ftp服務

CentOS:service vsftpd restart
CentOS7:/bin/systemctl restart vsftpd.service

9:瀏覽器訪問測試

ftp://ip

10:開機啓動FTP

命令:chkconfig vsftpd on

三:FTP工具類代碼

package hhxy.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
/**
 * ftp上傳下載工具類
 * @author 李偉康
 *
 */
public class FtpUtil {

	/** 
	 * Description: 向FTP服務器上傳文件 
	 * @param host FTP服務器hostname 
	 * @param port FTP服務器端口 
	 * @param username FTP登錄賬號 
	 * @param password FTP登錄密碼 
	 * @param basePath FTP服務器基礎目錄
	 * @param filePath FTP服務器文件存放路徑。例如分日期存放:/2015/01/01。文件的路徑爲basePath+filePath
	 * @param filename 上傳到FTP服務器上的文件名 
	 * @param input 輸入流 
	 * @return 成功返回true,否則返回false 
	 */  
public static boolean uploadFile(String host, int port, String username, String password, String basePath,
			String filePath, String filename, InputStream input) {
		boolean result = false;
		FTPClient ftp = new FTPClient();
		try {
			int reply;
			ftp.connect(host, port);// 連接FTP服務器
			// 如果採用默認端口,可以使用ftp.connect(host)的方式直接連接FTP服務器
			ftp.login(username, password);// 登錄
			reply = ftp.getReplyCode();
			if (!FTPReply.isPositiveCompletion(reply)) {
				ftp.disconnect();
				return result;
			}
			//切換到上傳目錄
			if (!ftp.changeWorkingDirectory(basePath+filePath)) {
				//如果目錄不存在創建目錄
				String[] dirs = filePath.split("/");
				String tempPath = basePath;
				for (String dir : dirs) {
					if (null == dir || "".equals(dir)) continue;
					tempPath += "/" + dir;
					if (!ftp.changeWorkingDirectory(tempPath)) {
						if (!ftp.makeDirectory(tempPath)) {
							return result;
						} else {
							ftp.changeWorkingDirectory(tempPath);
						}
					}
				}
			}
			//設置上傳文件的類型爲二進制類型
			ftp.setFileType(FTP.BINARY_FILE_TYPE);
			ftp.enterLocalPassiveMode();
			//上傳文件
			if (!ftp.storeFile(filename, input)) {
			
				return result;
			}
			input.close();
			ftp.logout();
			result = true;
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (ftp.isConnected()) {
				try {
					ftp.disconnect();
				} catch (IOException ioe) {
				}
			}
		}
		return result;
	}
	
	/** 
	 * Description: 從FTP服務器下載文件 
	 * @param host FTP服務器hostname 
	 * @param port FTP服務器端口 
	 * @param username FTP登錄賬號 
	 * @param password FTP登錄密碼 
	 * @param remotePath FTP服務器上的相對路徑 
	 * @param fileName 要下載的文件名 
	 * @param localPath 下載後保存到本地的路徑 
	 * @return 
	 */  
	public static boolean downloadFile(String host, int port, String username, String password, String remotePath,
			String fileName, String localPath) {
		boolean result = false;
		FTPClient ftp = new FTPClient();
		try {
			int reply;
			ftp.connect(host, port);
			// 如果採用默認端口,可以使用ftp.connect(host)的方式直接連接FTP服務器
			ftp.login(username, password);// 登錄
			reply = ftp.getReplyCode();
			if (!FTPReply.isPositiveCompletion(reply)) {
				ftp.disconnect();
				return result;
			}
			ftp.changeWorkingDirectory(remotePath);// 轉移到FTP服務器目錄
			ftp.enterLocalPassiveMode();
			FTPFile[] fs = ftp.listFiles();
			for (FTPFile ff : fs) {
				if (ff.getName().equals(fileName)) {
					File localFile = new File(localPath + "/" + ff.getName());
					OutputStream is = new FileOutputStream(localFile);
					ftp.retrieveFile(ff.getName(), is);
					is.close();
				}
			}

			ftp.logout();
			result = true;
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (ftp.isConnected()) {
				try {
					ftp.disconnect();
				} catch (IOException ioe) {
				}
			}
		}
		return result;
	}
	
	public static void main(String[] args) {
		try {  
			FileInputStream input=new  FileInputStream("E:\\1.jpg");		
			boolean result=FtpUtil.uploadFile("192.168.206.11",21, "ftpuser","ftpuser", "./", "/", "4.jpg", input);
			System.out.println(result); 

	    } catch (Exception e) {  
	        e.printStackTrace();  
	    }  
	}
}

四:FTP整合Web

1:pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>hhxy</groupId>
  <artifactId>ftpClientWeb</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  <properties>
		<servlet-version>3.0.1</servlet-version>
		<jsp-version>2.2</jsp-version>
		<jstl-version>1.2</jstl-version>
		<spring-version>4.1.6.RELEASE</spring-version>
		<aspectjweaver-version>1.8.6</aspectjweaver-version>
		<mybatis-version>3.2.7</mybatis-version>
		<mybatis-spring-version>1.2.3</mybatis-spring-version>
		<log4j-version>1.2.17</log4j-version>
		<mysql-connector-java-version>5.1.38</mysql-connector-java-version>
		<jackson-version>2.4.1</jackson-version>
		<commons-fileupload-version>1.3.1</commons-fileupload-version>
	</properties>
	<dependencies>
		<!-- ftpclient -->
		<dependency>
			<groupId>commons-net</groupId>
			<artifactId>commons-net</artifactId>
			<version>3.3</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>${servlet-version}</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>jsp-api</artifactId>
			<version>${jsp-version}</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>jstl</groupId>
			<artifactId>jstl</artifactId>
			<version>${jstl-version}</version>
		</dependency>
		<!-- spring -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring-version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>${spring-version}</version>
		</dependency>
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjweaver</artifactId>
			<version>${aspectjweaver-version}</version>
		</dependency>
		<!-- mybatis -->
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis</artifactId>
			<version>${mybatis-version}</version>
		</dependency>
		<!-- mybatis和spring整合 -->
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis-spring</artifactId>
			<version>${mybatis-spring-version}</version>
		</dependency>
		<!-- log4j 日誌 -->
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>${log4j-version}</version>
		</dependency>
		<!-- mysql 驅動類 -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>${mysql-connector-java-version}</version>
		</dependency>
		<!-- jackson -->
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>${jackson-version}</version>
		</dependency>
		<!-- apache 圖片上傳 -->
		<dependency>
			<groupId>commons-fileupload</groupId>
			<artifactId>commons-fileupload</artifactId>
			<version>${commons-fileupload-version}</version>
		</dependency>
	</dependencies>
	<build>
		<resources>
			<resource>
				<directory>src/main/resources</directory>
				<includes>
					<include>**/*.xml</include>
					<include>**/*.properties</include>
				</includes>
			</resource>
		</resources>
		<plugins>
			<plugin>
				<groupId>org.apache.tomcat.maven</groupId>
				<artifactId>tomcat7-maven-plugin</artifactId>
				<version>2.2</version>
				<configuration>
					<!-- 控制tomcat的端口號 -->
					<port>80</port>
					<!-- 項目發佈到tomcat的名稱 -->
					<!-- /相當於把項目發佈名稱爲ROOT -->
					<path>/</path>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

2:web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee                       
	http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
	<!-- 上下文參數 -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:applicationContext.xml</param-value>
	</context-param>
	<!-- 監聽器 -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	<!-- SpringMVC前端控制器 -->
	<servlet>
		<servlet-name>springmvc</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:springmvc.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>springmvc</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>
	<!-- 字符編碼過濾器 -->
	<filter>
		<filter-name>encoding</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>utf-8</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>encoding</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
</web-app>

3:applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx" 
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd" default-autowire="byName">
     
    <context:component-scan base-package="hhxy.service.impl"></context:component-scan>
    <!-- 加載屬性文件 -->
    <context:property-placeholder location="classpath:my.properties"/>  
</beans>

4:springmvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">
   
    <!-- 掃描註解 -->
    <context:component-scan base-package="hhxy.controller"></context:component-scan>
    <!-- 註解驅動 -->
    <mvc:annotation-driven></mvc:annotation-driven>
    <!-- 靜態資源 -->
    <mvc:resources location="/js/" mapping="/js/**"></mvc:resources>
    <mvc:resources location="/images/" mapping="/images/**"></mvc:resources>
    <mvc:resources location="/files/" mapping="/files/**"></mvc:resources>
    <!-- Multipart解析器 -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>
</beans>

5:my.properties

#@Value("${ftpclient.host}")
#private String host;
#@Value("${ftpclient.port}")
#private int port;
#@Value("${ftpclient.username}")
#private String username;
#@Value("${ftpclient.password}")
#private String password;
#@Value("${ftpclient.basePath}")
#private String basePath;
#@Value("${ftpclient.filepath}")
#private String filePath;
ftpclient.host=192.168.126.129
ftpclient.port = 21
ftpclient.username = ftpuser
ftpclient.password = ftpuser
ftpclient.basePath = /home/ftpuser
ftpclient.filepath = /

6:index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="upload" method="post" enctype="multipart/form-data">
	<input type="file" name="file"/><input type="submit" value="上傳"/>
</form>
</body>
</html>

7:UploadController.java

package hhxy.controller;

import java.io.IOException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;

import hhxy.service.UploadService;

@Controller
public class UploadController {
	@Autowired@Qualifier("uploadServiceImpl")
	private UploadService uploadServiceImpl;
	@RequestMapping("upload")
	public String upload(MultipartFile file) {
		try {
			boolean result = uploadServiceImpl.upload(file);
			if(result){
				return "/success.jsp";
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return "/error.jsp";
	}
}

8: UploadService.java

package hhxy.service;

import java.io.IOException;

import org.springframework.web.multipart.MultipartFile;

public interface UploadService {
	boolean upload(MultipartFile file) throws IOException;
}

9: UploadServiceImpl.java

package hhxy.service.impl;

import java.io.IOException;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import hhxy.service.UploadService;
import hhxy.utils.FtpUtil;

@Service
public class UploadServiceImpl implements UploadService {
	@Value("${ftpclient.host}")
	private String host;
	@Value("${ftpclient.port}")
	private int port;
	@Value("${ftpclient.username}")
	private String username;
	@Value("${ftpclient.password}")
	private String password;
	@Value("${ftpclient.basePath}")
	private String basePath;
	@Value("${ftpclient.filepath}")
	private String filePath;
	
	@Override
	public boolean upload(MultipartFile file) throws IOException {
		String fileName = UUID.randomUUID()+file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
		return FtpUtil.uploadFile(host, port, username, password, basePath, filePath, fileName, file.getInputStream());
	}

}

10:FtpUtil.java

package hhxy.utils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;

public class FtpUtil {
	public static boolean uploadFile(String host, int port, String username, String password, String basePath,
			String filePath, String filename, InputStream input) {
		boolean result=false;
		FTPClient ftp=new FTPClient();
		try {
			int reply;
			ftp.connect(host,port);//連接FTP服務器
			//如果採用默認端口可以使用ftp.connect(host)
			ftp.login(username, password);//登陸
			reply=ftp.getReplyCode();
			if(!FTPReply.isPositiveCompletion(reply)) {
				ftp.disconnect();
				return result;
			}
			//切換到上傳目錄
			if(!ftp.changeWorkingDirectory(basePath+filename)) {
				String[] dirs=filePath.split("/");
				String tempPath=basePath;
				for(String dir:dirs) {
					if(null==dir||"".equals(dir)) {
						continue;
					}
					tempPath="/"+dir;
					if(!ftp.changeWorkingDirectory(tempPath)) {
						if(!ftp.makeDirectory(tempPath)) {
							return result;
						}else {
							ftp.changeWorkingDirectory(tempPath);
						}
					}
				}
			}
			//設置上傳文件的類型爲二進制類型
			ftp.setFileType(FTP.BINARY_FILE_TYPE);
			ftp.enterLocalPassiveMode();
			//上傳文件
			if(!ftp.storeFile(filename, input)) {
				return result;
			}
			input.close();
			ftp.logout();
			result=true;
			
		}catch (IOException e) {
			// TODO: handle exception
			e.printStackTrace();
		}finally {
			if(ftp.isConnected()) {
				try {
					ftp.disconnect();
				}catch (IOException ioe) {
					// TODO: handle exception
					ioe.printStackTrace();
				}
			}
		}
		return result;
	}
	public static boolean downloadFile(String host, int port, String username, String password, String remotePath,
			String fileName, String localPath) {
		boolean result=false;
		FTPClient ftp=new FTPClient();
		try {
			int reply;
			ftp.connect(host,port);
			ftp.login(username, password);
			reply=ftp.getReplyCode();
			if(!FTPReply.isPositiveCompletion(reply)) {
				ftp.disconnect();
				return result;
			}
			ftp.changeWorkingDirectory(remotePath);
			ftp.enterLocalPassiveMode();
			FTPFile[] fs=ftp.listFiles();
			for(FTPFile ff:fs) {
				if(ff.getName().equals(fileName)) {
					File localFile=new File(localPath);
					OutputStream is=new FileOutputStream(localFile);
					ftp.retrieveFile(ff.getName(), is);
					is.close();
					
				}
			}
			ftp.logout();
			result=true;
		}catch (IOException e) {
			// TODO: handle exception
			e.printStackTrace();
		}finally {
			if(ftp.isConnected()) {
				try {
					ftp.disconnect();
				}catch (IOException ioe) {
					// TODO: handle exception
					ioe.printStackTrace();
				}	
			}
		}
		return result;
	}
}

五:配置Nginx反向代理

1:安裝Nginx

https://blog.csdn.net/qq_36297434/article/details/97661620

2:配置權限

在conf/nginx.conf中配置:user ftpuser;

3:配置反向代理

 server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {      
            root   /home/ftpuser;
            index  index.jpg;
        }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章