VSFTPD + NGINX

根据北京尚学堂公开教学视频学习

文档、资料和视频:

链接:https://pan.baidu.com/s/1i0zT9KUjNKpexvPHLi10xw 
提取码:eef4 
 

 

壹、VSFTPD 简介

1、Linux 的组件(一款软件),安装到 Linux 后通过 java 代码(FtpClient)实 现文件上传

2、VSFTPD 基于 FTP 协议

3、为什么要使用 VSFTPD

     3.1、之前实现文件上传

VSFTPD + NGINX_第1张图片

    3.2 使用 VSFTPD 后优化

         3.2.1、如果希望在客户端直接访问图片服务器中的图片,由于 VSFTPD 是基于 FTP 协议的,客户端浏览器是需要通过                      http 协议访 问图片.

         3.2.2、解决办法使用 Nginx 进行反向代理

          因为nginx只能代理http协议,对于和VSFTPD是不能被访问的,但是,我们可以将nginx和VSFTPD处于一台机器中,给Nginx操作VSFTPD的权利即可

VSFTPD + NGINX_第2张图片

4、可以使用格式在浏览器中访问到对应的图片(不推荐这样使用)

     4.1 在谷歌浏览器中直接访问到 ftpuser 目录

     4.2 IE 中访问的是 linux 的根目录

ftp://ftpuser:[email protected]

 

 

贰、FtpClient

 

1、java 技术,使用 FtpClient 使用使用 java 代码上传文件到 vsftpd 服务端

 导入依赖

	
	    commons-net
	    commons-net
	    3.6
	


2、代码实例

package com.tk.ftpclient;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.SocketException;

import org.apache.commons.net.ftp.FTPClient;

public class Test {

	public static void main(String[] args) throws SocketException, IOException {
		FTPClient client = new FTPClient();
		
		//IP地址和端口号    写在登录之前
		client.connect("192.168.17.131", 21);
		//用户名和密码
		client.login("ftpuser", "1327148745");
		//设置文件类型
		client.setFileType(FTPClient.BINARY_FILE_TYPE); 
		
		//在本机上找一张图片上传
		InputStream is = new FileInputStream("C:/Users/84741/Desktop/ssss/0.0.jpg");
		
		//设置上传目录	需要实现创建好文件,并赋予权限	  
		client.changeWorkingDirectory("/home/ftpuser/aaa");
		
		//存储时的名称
		client.storeFile("abc11.jpg", is);
		//退出
		client.logout();
		
		//同名文件上传会覆盖原有内容
		System.out.println("上传成功");
	
	}
}

 

3、FtpUtil工具类

package com.tk.utils;

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上传下载工具类
 */
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);
			//上传文件
			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服务器目录
			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 in=new FileInputStream(new File("C:/Users/84741/Desktop/ssss/0.0.jpg"));  
	        boolean flag = uploadFile("192.168.17.131", 21, "ftpuser", "1327148745", "/home/ftpuser","ccc", "abc2.png", in);  
	        System.out.println(flag);  
	    } catch (FileNotFoundException e) {  
	        e.printStackTrace();  
	    }  
	}
}

 

 

3. 使用 web 项目结合 FTPClient 完成

VSFTPD + NGINX_第3张图片

 

前台

	

控制器

    @RequestMapping("upload")
	public String upload(MultipartFile file) {
		 try {
			boolean upload = uploadService.upload(file);
			if(upload) {
				return "success.jsp";
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return "error.jsp";
	}

服务层

@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("."));
		System.out.println(fileName);
		return FtpUtil.uploadFile(host, port, username, password, basePath, filePath, fileName, file.getInputStream());
	}
}

软编码:ftpclient.properties(需要在applicationContext.xml文件中配置加载属性文件)

ftpclient.host = 192.168.17.131
ftpclient.port = 21
ftpclient.username = ftpuser
ftpclient.password = 1327148745
ftpclient.basePath = /home/ftpuser
ftpclient.filePath = /

	
	

 

叁、反向代理和正向代理

1、正向代理

     1.1 客户端知道最终要访问的服务器地址(例如)

VSFTPD + NGINX_第4张图片

2. 反向代理

    1.2 客户端只知道代理服务器地址,而不知道真实访问的服务器地址.

VSFTPD + NGINX_第5张图片

 

 

 

 

肆、nginx 配置(已经安装完成)

 

1. 进入到 nginx/conf 文件夹修改 nginx.conf

     1.1 赋予 ftpuser 用户权限

      1.2 设置代理的目录

            1.2.1 root : 代理的目录

            1.2.2 index: 欢迎项

                 1.2.3 如果只配置 root 不配置 index,在浏览器输入 ip 后依然报 403

VSFTPD + NGINX_第6张图片

 

 

 

 

完成一个简单的功能吧(基于SSM+VSFTPD+NGINX)

需求:类似于空间说说的上传,可以上传多张图片

VSFTPD + NGINX_第7张图片

 

 

数据库设计:(建表语句丢失了,直接看结构)

1、feel表:

2、picture表:

 

首先开启,VSFTPD服务,并且使用NGINX代理VSFTPD存储上传文件的空间

然后:正常的SSM开发流程

注意:

前台页面

VSFTPD + NGINX_第8张图片

使用了kindeditor里面的一些样式

图片是需要先单独上通过VSFTPD上传到存储空间中,就如图上图中的按钮批量上传,下图为详细

VSFTPD + NGINX_第9张图片

VSFTPD + NGINX_第10张图片

图片提交的  Controller

	@RequestMapping("upload")
	@ResponseBody
	public Map upload(MultipartFile imgFile){
		try {
			Map map = uploadService.upload(imgFile);
			return map;
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

图片提交 Service (利用FTP上传的工具类)

	@Override
	public Map upload(MultipartFile imgFile) throws IOException {
		String fileName = UUID.randomUUID().toString()+imgFile.getOriginalFilename().substring(imgFile.getOriginalFilename().lastIndexOf("."));
		boolean result = FtpUtil.uploadFile(host, port, username, password, basePath, filePath, fileName, imgFile.getInputStream());
		Map map = new HashMap();
		if(result) {
			map.put("error", 0);
			map.put("url", "http://192.168.17.131/aaa/"+fileName);
		}else {
			map.put("error", 1);
			map.put("url", "图片上传失败!!!");
		}
		return map;
	}

 

返回map是因为kindeditor上传文件的返回格式为Json

kindeditor的文档

VSFTPD + NGINX_第11张图片

 

 

页面的代码

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>




Insert title here







	
标题:
图片:
感受:

 

上传说说信息(正常的上传操作)

控制器

	@RequestMapping("insert")
	public String insert(Feel feel,@RequestParam("imgs")List imgs) {
		int index = uploadService.insFeel(feel, imgs);
		if(index > 0)
			return "success.jsp";
		
		return "error.jsp";
	}
public int insFeel(Feel feel, List imgs) {
		//通过ID生成工具类生成ID      ——》时间戳+随机数
		long id = IDUtils.genItemId();
		feel.setId(id);
		//上传说说数据
		int index = feelMapper.insFeel(feel);
		if(index > 0) {
			//把图片也全部上传
			for (String string : imgs) {
				Picture picture = new Picture();
				picture.setFid(id);
				picture.setPath(string);
				index += pictureMapper.insPicture(picture);
			}
			//是否全部上传成功
			if(index ==imgs.size()+1) {
				return 1;
			}
		}
		
		return 0;
	}

 

 

 

 

你可能感兴趣的:(互联网架构)