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;
        }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值