【SpringBoot】上传图片到Linux服务器(html+ajax+jquery+ftpclient+nginx)

最近在做毕业设计,需要做一个批量上传图片的功能。


	4.0.0
	com.kclub
	tenement_project
	war
	0.0.1-SNAPSHOT
	tenement_project Maven Webapp
	http://maven.apache.org
	
	
		org.springframework.boot
		spring-boot-starter-parent
		1.5.2.RELEASE
		
	
	
		UTF-8
		UTF-8
		1.7
	
	
		
		
			org.springframework.boot
			spring-boot-starter
		
		
			org.springframework.boot
			spring-boot-starter-test
			test
		
		
		
			org.springframework.boot
			spring-boot-starter-web
		
		
		
			org.springframework.boot
			spring-boot-devtools
			true
			true
		
		
		
			org.mybatis.spring.boot
			mybatis-spring-boot-starter
			1.1.1
		
		
			mysql
			mysql-connector-java
		
		
		
			com.alibaba
			fastjson
			1.2.32
		
		
		
			org.springframework.boot
			spring-boot-starter-thymeleaf
		
		
			net.sourceforge.nekohtml
			nekohtml
		
		
		
			org.apache.commons
			commons-email
			1.4
		
		
		
			commons-net
			commons-net
			3.3
		
		
		
			aliyun-java-sdk-core
			aliyun-java-sdk-core
			3.2.3
		
		
			aliyun-java-sdk-dysmsapi
			aliyun-java-sdk-dysmsapi
			1.0
		
		
		
		
		
			commons-io
			commons-io
			2.1
		
		
			commons-fileupload
			commons-fileupload
			1.3
		
		
		
			commons-httpclient
			commons-httpclient
			3.1
		
		
		
			commons-logging
			commons-logging
			1.1.1
		
		
		
			org.apache.commons
			commons-lang3
			3.4
		
	
	
		tenement_project
		
			
				
				
					org.springframework.boot
					spring-boot-maven-plugin
				
				
				
					org.springframework.boot
					spring-boot-maven-plugin
					
						
						true
					
				
			
		
	
	
		
			spring-milestones
			Spring Milestones
			https://repo.spring.io/milestone
			
				false
			
		
	

先介绍一下,前端的代码:

①在前端html中使用file类型的input标签,

②js操作,获取file,存在一个fileStack数组中,并通过,jquery each方法,将图片回写

  到Html中。

【SpringBoot】上传图片到Linux服务器(html+ajax+jquery+ftpclient+nginx)_第1张图片

    

$(function() {

	// 图片上传
	fileStack = [];// 存放图片文件的数组
	// 当change时调用addFiles()
	$("#uploadImages").change(function() {
		addFiles();
	})
	// 删除操作,操作这个fileStack
	function addFiles() {
		var files = document.querySelector("input[type=file]");
		var filelist = files.files;// 选择图片列表
		$.each(filelist,function(i, file) {fileStack.push(file);
							var reader = new FileReader();
							reader.onload = function(e) {
								var result = this.result;
								var img = document.createElement("img");
								// img.src = result;
								var i = 0;
								$("#imagesUl").append("
  • " + "
    " + "
    " + "
  • "); }; reader.readAsDataURL(file); }); }        })

    ③提交数据到后台,用each方法将上述fileStack数组添加到formdata中

    var formdata = new FormData();//定义一个formdata对象

    $.each(fileStack, function(i, file) {// 所有文件都要放到同一个名字下面:如files
    formdata.append("file", file);
    });
    	function submitMethod(formdata) {
    		$.ajax({
    			type : 'POST',
    			url : "/tenement/uploadImages.action",
    			dataType : 'json',
    			data : formdata,
    			cache : false,
    			processData : false,
    			contentType : false,
    			success : function(responseStr) {
    				if (responseStr == "1") {
    					swal("发布成功,信息审核中", "", "success");
    				} else {
    					swal("发布失败,未知错误", "", "error");
    				}
    			},
    			error : function(responseStr) {
    				swal("发布失败,未知错误", "", "error");
    			}
    		});
    	}

    后台代码:

    Controller层代码:

    	/**
    	 * 数据上传
    	 * 
    	 * @param albumId
    	 * @param files
    	 * @return
    	 * @throws IOException
    	 */
    	@RequestMapping("/uploadImages.action")
    	public @ResponseBody String uploadFiles(@RequestParam("albumId") Integer albumId,
    			@RequestParam("file") MultipartFile[] files) throws IOException {
    		logger.info("【上传图片controller】");
    		FtpConfig ftpConfig = new FtpConfig();
    		List photoList = new ArrayList();
    
    		for (MultipartFile file : files) {
    			Photo photo = new Photo();
    			String oldName = file.getOriginalFilename();// 获取图片原来的名字
    			String picNewName = UploadUtils.generateRandonFileName(oldName);// 通过工具类产生新图片名称,防止重名
    			String picSavePath = UploadUtils.generateRandomDir(picNewName);// 通过工具类把图片目录分级
    			/*
    			 * photo.setPhotoUrl(picSavePath + "/");//
    			 * 设置图片的url--》就是存储到数据库的字符串url photo.setAlbumId(albumId);//
    			 * 设置图片所属相册id photo.setUser_id("wk");
    			 * photo.setPhoteName(picNewName);
    			 */
    			photoList.add(photo);
    			FtpUtil.pictureUploadByConfig(ftpConfig, picNewName, picSavePath, file.getInputStream());// 上传到图片服务器的操作
    			// 添加到数据库
    		}
    		iPhotoService.uploadImages(photoList);
    		return state.Success;
    	}

    UploadUtils.java,获得文件新名字,生成一二级目录

    package com.tenement.utils.ftp_images_server;
    
    import java.io.File;
    import java.util.UUID;
    
    public class UploadUtils {
    
    	/**
    	 * 得到真实文件名
    	 * 
    	 * @param fileName
    	 * @return
    	 */
    	public static String subFileName(String fileName) {
    		// 查找最后一个 \ (文件分隔符)位置
    		int index = fileName.lastIndexOf(File.separator);
    		if (index == -1) {
    			// 没有分隔符,说明是真实名称
    			return fileName;
    		} else {
    			return fileName.substring(index + 1);
    		}
    	}
    
    	/**
    	 * 获得随机UUID文件名
    	 * 
    	 * @param fileName
    	 * @return
    	 */
    	public static String generateRandonFileName(String fileName) {
    		// 首相获得扩展名,然后生成一个UUID码作为名称,然后加上扩展名
    		String ext = fileName.substring(fileName.lastIndexOf("."));
    		return UUID.randomUUID().toString() + ext;
    	}
    
    	public static String generateRandonFileName() {
    		return UUID.randomUUID().toString();
    	}
    
    	/**
    	 * 获得hashcode 生成二级目录
    	 * 
    	 * @param uuidFileName
    	 * @return
    	 */
    	public static String generateRandomDir(String uuidFileName) {
    		int hashCode = uuidFileName.hashCode();// 得到它的hashcode编码
    		// 一级目录
    		int d1 = hashCode & 0xf;
    		// 二级目录
    		int d2 = (hashCode >> 4) & 0xf;
    		return "/" + d1 + "/" + d2;
    	}
    
    	public static void main(String[] args) {
    		System.out.println(generateRandonFileName());
    	}
    }
    

    FtpUtil.java,上传文件到服务器上的工具类

    package com.tenement.utils.ftp_images_server;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    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;
    
    /**
     * 正在使用
     * @author wk
     *
     */
    public class FtpUtil {
    
    	private static final Log logger = LogFactory.getLog(FtpUtil.class);
    	public static String pictureUploadByConfig(FtpConfig ftpConfig, String picNewName, String picSavePath,
    			InputStream inputStream) throws IOException {
    		logger.info("【pictureUploadByConfig】");
    		String picHttpPath = null;
    
    		boolean flag = uploadFile(ftpConfig.getFTP_ADDRESS(), ftpConfig.getFTP_PORT(), ftpConfig.getFTP_USERNAME(),
    				ftpConfig.getFTP_PASSWORD(), ftpConfig.getFTP_BASEPATH(), picSavePath, picNewName, inputStream);
    
    		if (!flag) {
    			return picHttpPath;
    		}
    		picHttpPath = ftpConfig.getIMAGE_BASE_URL() + picSavePath + "/" + picNewName;
    		logger.info("【picHttpPath】"+picHttpPath);
    		return picHttpPath;
    	}
    
    	/**
    	 * Description: 向FTP服务器上传文件
    	 * 
    	 * @param host
    	 *            FTP服务器hostname
    	 * @param port
    	 *            FTP服务器端口
    	 * @param username
    	 *            FTP登录账号
    	 * @param password
    	 *            FTP登录密码
    	 * @param basePath
    	 *            FTP服务器基础目录
    	 * @param filePath
    	 *            FTP服务器文件存放路径。
    	 * @param filename
    	 *            上传到FTP服务器上的文件名
    	 * @param input
    	 *            输入流
    	 * @return 成功返回true,否则返回false
    	 */
    	public static boolean uploadFile(String host, String ftpPort, String username, String password, String basePath,
    			String filePath, String filename, InputStream input) {
    		int port = Integer.parseInt(ftpPort);
    		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();// 这个设置允许被动连接--访问远程ftp时需要
    			// 上传文件
    			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;
    	}
    }
    

    FtpConfig.java实体类

    package com.tenement.utils.ftp_images_server;
    
    /**
     * ftp服务器配置实体类
     * 
     * @author wk
     *
     */
    public class FtpConfig {
    
    	/**
    	 * 获取IP地址
    	 */
    	private String FTP_ADDRESS = "服务器ip地址";
    
    	/**
    	 * 端口号
    	 */
    	private String FTP_PORT = "21";
    
    	/**
    	 * 用户名
    	 */
    	private String FTP_USERNAME = "ftp用户名";
    
    	/**
    	 * 密码
    	 */
    	private String FTP_PASSWORD = "ftp用户密码";
    
    	/**
    	 * 基本路径,用户图片
    	 */
    	private String FTP_BASEPATH = "/home/ftptest/tenement/house_images";
    
    	/**
    	 * 下载地址地基础url,这个是配置的图片服务器的地址,最后访问图片时候,需要用该基础地址    
    	 */
    	private String IMAGE_BASE_URL = "url";
    
    	public String getFTP_ADDRESS() {
    		return FTP_ADDRESS;
    	}
    
    	public void setFTP_ADDRESS(String fTP_ADDRESS) {
    		FTP_ADDRESS = fTP_ADDRESS;
    	}
    
    	public String getFTP_PORT() {
    		return FTP_PORT;
    	}
    
    	public void setFTP_PORT(String fTP_PORT) {
    		FTP_PORT = fTP_PORT;
    	}
    
    	public String getFTP_USERNAME() {
    		return FTP_USERNAME;
    	}
    
    	public void setFTP_USERNAME(String fTP_USERNAME) {
    		FTP_USERNAME = fTP_USERNAME;
    	}
    
    	public String getFTP_PASSWORD() {
    		return FTP_PASSWORD;
    	}
    
    	public void setFTP_PASSWORD(String fTP_PASSWORD) {
    		FTP_PASSWORD = fTP_PASSWORD;
    	}
    
    
    
    	public String getIMAGE_BASE_URL() {
    		return IMAGE_BASE_URL;
    	}
    
    	public void setIMAGE_BASE_URL(String iMAGE_BASE_URL) {
    		IMAGE_BASE_URL = iMAGE_BASE_URL;
    	}
    
    	public String getFTP_BASEPATH() {
    		return FTP_BASEPATH;
    	}
    
    	public void setFTP_BASEPATH(String fTP_BASEPATH) {
    		FTP_BASEPATH = fTP_BASEPATH;
    	}
    
    }
    

    在这之前在项目pom.xml引入相关jar包

      
      
      
      commons-io  
      commons-io  
      2.1  
      
      
      
      commons-fileupload  
      commons-fileupload  
      1.3  
      
      
      
      commons-net  
      commons-net  
      3.3  
    

    整体思路:

        前台获取获取file数组,传到后台,使用ftpclient类,将file传到linux服务器

    上,在数据库中存储的是图片的一二级目录和图片新名字。

    最后访问时通过nginx反向代理功能来访问服务器上的图片

    如何利用Nginx搭建图片服务器参照博客:

    https://blog.csdn.net/qq_36762765/article/details/79539226

    参考:https://blog.csdn.net/maoyuanming0806/article/details/78068091

    你可能感兴趣的:(SpringBoot)