Java实现图片分片上传

1、需求
最近前端同事想拥有一个图片素材库并针对大图实现压缩。最开始提供的接口只是简单的图片上传,实现压缩图片技术是缩略图和webp压缩并上传到ftp,这里出现一个问题前端会上传一些比较大的图片,项目中针对服务设置了超时时间,经常出现接口超时。网上有很多实现分片上传图片,自己也想着实现图片分片上传。

2、原理
客户端将图片分割成多个小的分片,然后再将这些分片一片一片的上传给服务端,服务端拿到分片后通过ftp追加最后合成一个整图。这里需要有一个唯一标识来分片属于一个整图,这边和前端约束前端生成一个唯一的标识(后端生成唯一标识响应给前端也可以)传给后端,这边通过唯一标识生成请求响应标识,前端取到之后在设置请求头,后端取请求头中的参数做区分。

3、实现

/**
	 * @param image 
	 * @param imageId 唯一标识
	 * @param chunk 当前分片数
	 * @param chunk 总分片数 
	 * @param imageName 图片名
	 */
public RetInfo uploadImage(HttpServletRequest request, HttpServletResponse response,MultipartFile image, String imageId, int chunk, int chunks,String imageName) {
 	String rename = imageId; 
	if (request.getHeader("image-"+imageId) != null) {
		rename = request.getHeader("image-"+imageId);
		Integer size = Integer.valueOf(request.getHeader("size-" + imageId));
		Integer attribute = Integer.valueOf(request.getHeader("chunk-" + imageId));
 		if (attribute != chunk) {
			return RetInfo.failBuilder("参数非法");
		}
		response.setHeader("image-"+imageId,rename);
		response.setHeader("chunk-"+imageId,chunk+1 + "");
		response.setHeader("size-"+imageId,size + image.getSize() + "");
   } else {
        response.setHeader("image-"+imageId,rename);
		response.setHeader("chunk-"+imageId,chunk+1 + "");
		response.setHeader("size-"+imageId,image.getSize() + "");
  }
  。。。。。。。。
}

这里在请求中记录了下一个chunk分片数和下一次请求参数做判断,判断是否请求合法。
这里在记录下ftp工具使用。

/**
	 * 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 appendFile(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(basePath != null && basePath != ""){
				if (!ftp.changeWorkingDirectory(basePath)) {
					if (!ftp.makeDirectory(basePath)) {
						return result;
					}
				}
			}
			//设置PassiveMode传输
			ftp.enterLocalPassiveMode();
			//设置以二进制流的方式传输
			ftp.setFileType(FTP.BINARY_FILE_TYPE);
			ftp.setControlEncoding("GBK");

			//切换到上传目录
			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);
						}
					}
				}
			}

			//检查远程是否存在文件
			FTPFile[] fs = ftp.listFiles();
			FTPFile ftpFile = null;
			for (FTPFile ff : fs) {
				if (ff.getName().equals(fileName)) {
					//追加
					ftpFile = ff;
					break;
				}
			}
			if (ftpFile == null) {
				//新增
				//设置上传文件的类型为二进制类型
				ftp.setFileTransferMode(FTP.STREAM_TRANSFER_MODE);
				//上传文件
				if (!ftp.storeFile(fileName, input)) {
					return result;
				}
				input.close();
			} else {
				//追加
				long remoteSize = ftpFile.getSize();

				ftp.setRestartOffset(remoteSize);
				OutputStream out = ftp.appendFileStream(fileName);
				if (out != null) {
					byte[] bytes = new byte[1024];
					int c;
					while((c = input.read(bytes)) != -1){
						out.write(bytes, 0, c);
					}
					out.flush();
					out.close();
				}
				input.close();
			}
			ftp.logout();
			result = true;
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (ftp.isConnected()) {
				try {
					ftp.disconnect();
				} catch (IOException ioe) {
				}
			}
		}
		return result;
	}

压缩图片这里就不做说明了。有时间在介绍webp压缩

上面就是实现图片分片上传的方法,如果有什么不足之处或者觉得缺少了上面,可以直接评论哦,然后我会准时补上,或者给你们解决问题。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值