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

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

<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/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.kclub</groupId>
	<artifactId>tenement_project</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<name>tenement_project Maven Webapp</name>
	<url>http://maven.apache.org</url>
	<!-- 父级 -->
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.2.RELEASE</version>
		<relativePath />
	</parent>
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.7</java.version>
	</properties>
	<dependencies>
		<!-- start -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<!-- web application -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!-- spring-boot-devtools工具包 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<optional>true</optional>
			<scope>true</scope>
		</dependency>
		<!-- mybatis引入的依赖 -->
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>1.1.1</version>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
		</dependency>
		<!-- 引入fastjson插件 -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.32</version>
		</dependency>
		<!-- theymeleaf模板 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
		<dependency>
			<groupId>net.sourceforge.nekohtml</groupId>
			<artifactId>nekohtml</artifactId>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-email -->
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-email</artifactId>
			<version>1.4</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/commons-net/commons-net -->
		<dependency>
			<groupId>commons-net</groupId>
			<artifactId>commons-net</artifactId>
			<version>3.3</version>
		</dependency>
		<!-- 阿里短信服务jar/ -->
		<dependency>
			<groupId>aliyun-java-sdk-core</groupId>
			<artifactId>aliyun-java-sdk-core</artifactId>
			<version>3.2.3</version>
		</dependency>
		<dependency>
			<groupId>aliyun-java-sdk-dysmsapi</groupId>
			<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
			<version>1.0</version>
		</dependency>
		<!-- /阿里短信服务jar -->
		<!-- https://mvnrepository.com/artifact/com.aliyun/aliyun-java-sdk-core -->
		<!-- 文件上传 -->
		<dependency>
			<groupId>commons-io</groupId>
			<artifactId>commons-io</artifactId>
			<version>2.1</version>
		</dependency>
		<dependency>
			<groupId>commons-fileupload</groupId>
			<artifactId>commons-fileupload</artifactId>
			<version>1.3</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/commons-httpclient/commons-httpclient -->
		<dependency>
			<groupId>commons-httpclient</groupId>
			<artifactId>commons-httpclient</artifactId>
			<version>3.1</version>
		</dependency>
		<!-- commons-logging/commons-logging 日志 -->
		<dependency>
			<groupId>commons-logging</groupId>
			<artifactId>commons-logging</artifactId>
			<version>1.1.1</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
			<version>3.4</version>
		</dependency>
	</dependencies>
	<build>
		<finalName>tenement_project</finalName>
		<pluginManagement>
			<plugins>
				<!-- 项目打包,将springboot应用打包为可执行的jar或war文件 -->
				<plugin>
					<groupId>org.springframework.boot</groupId>
					<artifactId>spring-boot-maven-plugin</artifactId>
				</plugin>
				<!-- springloader -->
				<plugin>
					<groupId>org.springframework.boot</groupId>
					<artifactId>spring-boot-maven-plugin</artifactId>
					<configuration>
						<!-- fork: 如果没有该项配置,肯呢个devtools不会起作用, 即应用不会restart -->
						<fork>true</fork>
					</configuration>
				</plugin>
			</plugins>
		</pluginManagement>
	</build>
	<repositories>
		<repository>
			<id>spring-milestones</id>
			<name>Spring Milestones</name>
			<url>https://repo.spring.io/milestone</url>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</repository>
	</repositories>
</project>

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

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

<input type="file" multiple="multiple" id="uploadImages">

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

  到Html中。

    

$(function() {

	// 图片上传
	fileStack = [];// 存放图片文件的数组
	// 当<input type="file">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("<li class='img_box' data-index='"
														+ (i++)
														+ "' draggable='true'><img src='"
														+ result
														+ "'><div class='img_cover'></div><div class='toolbar_wrap'>"
														+ "<div class='opacity'></div>"
														+ "<div class='toolbar'>"
														+ "<a href='javascript:;' class='edit'></a><a href='javascript:;' class='delete'></a></div></div></li>");
							};
							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<Photo> photoList = new ArrayList<Photo>();

		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包

<!-- 加入上传文件组件 -->  
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->  
<dependency>  
  <groupId>commons-io</groupId>  
  <artifactId>commons-io</artifactId>  
  <version>2.1</version>  
</dependency>  
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->  
<dependency>  
  <groupId>commons-fileupload</groupId>  
  <artifactId>commons-fileupload</artifactId>  
  <version>1.3</version>  
</dependency>  
<!-- https://mvnrepository.com/artifact/commons-net/commons-net -->  
<dependency>  
  <groupId>commons-net</groupId>  
  <artifactId>commons-net</artifactId>  
  <version>3.3</version>  
</dependency>

整体思路:

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

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

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

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

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

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

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值