java-FastDFS服务器上传图片Demo

java中Maven项目使用fastDfs上传图片详解

1. 什么是FastDfs服务器

FastDFS是用 c 语言编写的一款开源的分布式文件系统,FastDFS 为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,使用FastDFS 很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务

2. fastDfs架构

FastDFS 架构包括 Tracker serverStorage server客户端请求 Tracker server 进行文件上传、下载,通过 Tracker server 调度最终由 Storage server 完成文件上传和下载

2.1 Tracker server 和 Storage server

Tracker server :作用是负载均衡和调度,通过 Tracker server 在文件上传时可以根据一些策略找到 Storage server 提供文件上传服务。可以将 tracker 称为追踪服务器或调度服务器

Storage server 作用是文件存储,客户端上传的文件最终存储在 Storage 服务器上,Storageserver 没有实现自己的文件系统而是利用操作系统的文件系统来管理文件,可以将storage 称为存储服务器

在这里插入图片描述
服务端两个角色:
Tracker:管理集群,tracker 也可以实现集群。每个 tracker 节点地位平等。收集Storage 集群的状态

Storage:实际保存文件 Storage 分为多个组,每个组之间保存的文件是不同的,每个组内部可以有多个成员,组成员内部保存的内容是一样的,组成员的地位是一致的,没有主从的概念

3. 文件上传流程

在这里插入图片描述
客户端上传文件后存储服务器将文件 ID 返回给客户端,此文件 ID 用于以后访问该文件的索引信息。文件索引信息包括:组名,虚拟磁盘路径,数据两级目录,文件名

  • 组名:文件上传后所在的 storage 组名称,在文件上传成功后有 storage 服务器返回,需要客户端自行保存
  • 虚拟磁盘路径: storage 配置的虚拟路径,与磁盘选项 store_path*对应。如果配置了store_path0 则是 M00,如果配置了 store_path1 则是 M01,以此类推
  • 数据两级目录: storage 服务器在每个虚拟磁盘路径下创建的两级目录,用于存储数据文件
  • 文件名: 与文件上传时不同。是由存储服务器根据特定信息生成,文件名包含:源存储服务器 IP 地址、文件创建时间戳、文件大小、随机数和文件拓展名等信息

4. 文件 下载流程

在这里插入图片描述

5. Maven项目使用fastDfs

  • 导入fastDfs依赖
		<dependency>
            <groupId>org.csource.fastdfs</groupId>
            <artifactId>fastdfs</artifactId>
            <version>1.2</version>
        </dependency>
  • fastDfs配置文件
# 这里写自己服务器的ip地址 
tracker_server=192.168.25.133:22122
  • 编写工具类
package utils;

import org.csource.common.NameValuePair;
import org.csource.fastdfs.ClientGlobal;
import org.csource.fastdfs.StorageClient1;
import org.csource.fastdfs.StorageServer;
import org.csource.fastdfs.TrackerClient;
import org.csource.fastdfs.TrackerServer;

public class FastDFSClient {

	private TrackerClient trackerClient = null;
	private TrackerServer trackerServer = null;
	private StorageServer storageServer = null;
	private StorageClient1 storageClient = null;
	
	public FastDFSClient(String conf) throws Exception {
		if (conf.contains("classpath:")) {
			conf = conf.replace("classpath:", this.getClass().getResource("/").getPath());
		}
		ClientGlobal.init(conf);
		trackerClient = new TrackerClient();
		trackerServer = trackerClient.getConnection();
		storageServer = null;
		storageClient = new StorageClient1(trackerServer, storageServer);
	}
	
	/**
	 * 上传文件方法
	 * <p>Title: uploadFile</p>
	 * <p>Description: </p>
	 * @param fileName 文件全路径
	 * @param extName 文件扩展名,不包含(.)
	 * @param metas 文件扩展信息
	 * @return
	 * @throws Exception
	 */
	public String uploadFile(String fileName, String extName, NameValuePair[] metas) throws Exception {
		String result = storageClient.upload_file1(fileName, extName, metas);
		return result;
	}
	
	public String uploadFile(String fileName) throws Exception {
		return uploadFile(fileName, null, null);
	}
	
	public String uploadFile(String fileName, String extName) throws Exception {
		return uploadFile(fileName, extName, null);
	}
	
	/**
	 * 上传文件方法
	 * <p>Title: uploadFile</p>
	 * <p>Description: </p>
	 * @param fileContent 文件的内容,字节数组
	 * @param extName 文件扩展名
	 * @param metas 文件扩展信息
	 * @return
	 * @throws Exception
	 */
	public String uploadFile(byte[] fileContent, String extName, NameValuePair[] metas) throws Exception {
		
		String result = storageClient.upload_file1(fileContent, extName, metas);
		return result;
	}
	
	public String uploadFile(byte[] fileContent) throws Exception {
		return uploadFile(fileContent, null, null);
	}
	
	public String uploadFile(byte[] fileContent, String extName) throws Exception {
		return uploadFile(fileContent, extName, null);
	}
}

  • 编写controller代码
package com.pyg.shop.controller;

import entity.Result;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import utils.FastDFSClient;

/**
 * @ Description
 * @ auther          宁宁小可爱
 * @ create          2020-01-30 11:35
 */
@RestController
@Transactional
@RequestMapping("/upload")
public class UploadController {

    /* 注入配置文件中的图片服务器地址 */
    @Value("${IMAGE_SERVER_URL}")
    private String IMAGE_SERVER_URL;
    /*
    * 上传图片
    * */
    @RequestMapping("pic")
    public Result uploadPic(MultipartFile file){
        try {
            /* 获取上传文件名字*/
            String filename = file.getOriginalFilename();
            /* 截取文件扩展名 */
            String extName = filename.substring(filename.lastIndexOf(".") + 1);
            /* 使用fastdfs工具类上传图片 */
            FastDFSClient dfsClient = new FastDFSClient("classpath:conf/client.conf");
            /* 上传图片 返回相对地址  协议+ip地址*/
            String url = dfsClient.uploadFile(file.getBytes(), extName);
            /* 组装绝对地址 */
            url = IMAGE_SERVER_URL+url;

            /* 无异常返回url */
            return new Result(true,url);

        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false,"图片上传失败");
        }
    }
}

  • 编写AngularJs-1controller代码
 /* 图片上传方法 */
    $scope.uploadFile = function () {
        /* 调用service方法 */
        uploadService.upload().success(function (response) {
            if (response.success){
                /* 上传成功 把图片地址赋值在url上 */
                $scope.image.url = response.message;
            }else {
                alert(response.message)
            }
        })
    }
  • 编写service代码
app.service("uploadService",function($http){
//	angularJS的文件上传
	this.upload=function(){
//		html5的对象
		var formData = new FormData();
		formData.append("file",file.files[0]); //file.files[0] js的取值方式  取到页面的第一个file
		return $http({
			method:'post',
			url:'../upload/pic', 
			data:formData,
			headers: {'Content-Type':undefined},  //enctype类型一定是 multipart/form-data
			transformRequest: angular.identity  //序列化上传的文件
		});
	}
})
  • 程序运行结果正常,图片已回显
    在这里插入图片描述
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叫我三胖哥哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值