spring cloud + fastdfs 塔建文件管理微服务

时间:2022-12-31 16:42:38

目前项目选择fastdfs作为服务中心,就用spring cloud + fastdfsClient作为文件管理的框架

这是pom.xml文件

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId> //用eure可作为服务发现框架
</dependency>
<dependency>
<groupId>net.oschina.zcx7878</groupId>
<artifactId>fastdfs-client-java</artifactId> //fastdfs-client
<version>1.27.0.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId> //接口说明文档
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
</dependency>
Application 里面的注解
@EnableDiscoveryClient@SpringBootApplication@Configuration@EnableSwagger2public class FilemanagerApplication {   public static void main(String[] args) {      SpringApplication.run(FilemanagerApplication.class, args);   }}
swagger配置在加载配置是

通过注解EnableSwagger2声明Swagger的可用性,此处会定义一个类型为Docket的bean,
关于docket类的说明如下:

A builder which is intended to be the primary interface into the swagger-springmvc framework.Provides sensible defaults and convenience methods for configuration.

Docket的select()方法会提供给swagger-springmvc framework的一个默认构造器(ApiSelectorBuilder),这个构造器为配置swagger提供了一系列的默认属性和便利方法。

@Configuration@EnableSwagger2public class SwaggerConfig {        @Bean        public Docket computeRestApi() {            return new Docket(DocumentationType.SWAGGER_2).groupName("filenamager")                    .select()  // 选择那些路径和api会生成document                    .apis(RequestHandlerSelectors.basePackage("com.cloud.fastdfs.filemanager.control")) // 拦截的包路径                    .paths(PathSelectors.any())// 拦截的接口路径                    .build();        }        private ApiInfo computeApiInfo() {            Contact contact = new Contact("XXXX", "XXXX", "XXXXX");            ApiInfo apiInfo = new ApiInfoBuilder()                    .title("并行计算服务 - API接口")                    .description("REST风格API")                    .contact(contact)                    .version("1.0")                    .build();            return apiInfo;        }}
fastdfsClient 的使用方式
@Componentpublic class FastDFSClient {    @Autowired    private FastConnectionPool connectionPool;    public String uploadFile(byte[] buff,String fileName)    {        return uploadFile(buff, fileName, null,null);    }    public String uploadFile(byte[] buff, String fileName, Map<String, String> metaList,String groupName) {        try {            NameValuePair[] nameValuePairs = null;            if (metaList != null) {                nameValuePairs = new NameValuePair[metaList.size()];                int index = 0;                for (Iterator<Map.Entry<String, String>> iterator = metaList.entrySet().iterator(); iterator.hasNext(); ) {                    Map.Entry<String, String> entry = iterator.next();                    String name = entry.getKey();                    String value = entry.getValue();                    nameValuePairs[index++] = new NameValuePair(name, value);                }            }            /** 获取可用的tracker,并创建存储server */ StorageClient1 storageClient = connectionPool.checkout();            String path = null;            if (!StringUtils.isEmpty(groupName)) {                // 上传到指定分组                path = storageClient.upload_file1(groupName, buff,                        FileUtil.getExtensionName(fileName), nameValuePairs);            } else {                path = storageClient.upload_file1(buff, FileUtil.getExtensionName(fileName),                        nameValuePairs);            }            /** 上传完毕及时释放连接 */ connectionPool.checkin(storageClient);            return path;        } catch (Exception e) {            e.printStackTrace();        }        return null;    }    public Map<String, String> getFileMetadata(String fileId)    {        try        {            /** 获取可用的tracker,并创建存储server */ StorageClient1 storageClient = connectionPool.checkout();            NameValuePair[] metaList = storageClient.get_metadata1(fileId);            /** 上传完毕及时释放连接 */ connectionPool.checkin(storageClient);            if (metaList != null)            {                HashMap<String, String> map = new HashMap<String, String>();                for (NameValuePair metaItem : metaList)                {                    map.put(metaItem.getName(), metaItem.getValue());                }                return map;            }        }        catch (Exception e)        {            e.printStackTrace();        }        return null;    }    public int deleteFile(String fileId)    {        try        {            /** 获取可用的tracker,并创建存储server */ StorageClient1 storageClient = connectionPool.checkout();            int i = storageClient.delete_file1(fileId);            /** 上传完毕及时释放连接 */ connectionPool.checkin(storageClient);            return i;        }        catch (Exception e)        {            e.printStackTrace();        }        return -1;    }    public byte[] downloadFile(String fileId)    {        try        {            /** 获取可用的tracker,并创建存储server */ StorageClient1 storageClient = connectionPool.checkout();            byte[] content = storageClient.download_file1(fileId);            /** 上传完毕及时释放连接 */ connectionPool.checkin(storageClient);            return content;        }        catch (IOException e)        {            e.printStackTrace();        }        catch (MyException e)        {            e.printStackTrace();        }        return null;    }    public FileInfo getFileInfo(String fileId)    {        try        {            /** 获取可用的tracker,并创建存储server */ StorageClient1 storageClient = connectionPool.checkout();            FileInfo fileInfo = storageClient.get_file_info1(fileId);            /** 上传完毕及时释放连接 */ connectionPool.checkin(storageClient);            return fileInfo;        }        catch (IOException e)        {            e.printStackTrace();        }        catch (MyException e)        {            e.printStackTrace();        }        return null;    }}
FastDFS client 连接池实现
@Componentpublic class FastConnectionPool {    private static final String FASTDFS_CONFIG = "client.conf";    /*空闲的连接池*/    private LinkedBlockingQueue<StorageClient1> idleConnectionPool = null;    /** 连接池默认最小连接数 */ private long minPoolSize = 10;    /** 连接池默认最大连接数 */ private long maxPoolSize = 30;    /** 默认等待时间(单位:秒) */ private long waitTimes = 200;    /** fastdfs客户端创建连接默认1次 */ private static final int COUNT = 1;    private Object obj = new Object();    TrackerServer trackerServer = null;    public FastConnectionPool()    {        /** 初始化连接池 */ poolInit();        /** 注册心跳 */ //HeartBeat beat = new HeartBeat(this);        //beat.beat();    }    public FastConnectionPool(long minPoolSize, long maxPoolSize, long waitTimes)    {        System.out.println("[线程池构造方法(ConnectionPool)][默认参数:minPoolSize=" + minPoolSize                + ",maxPoolSize=" + maxPoolSize + ",waitTimes=" + waitTimes + "]");        this.minPoolSize = minPoolSize;        this.maxPoolSize = maxPoolSize;        this.waitTimes = waitTimes;        /** 初始化连接池 */ poolInit();        /** 注册心跳 */ // HeartBeat beat = new HeartBeat(this);       //beat.beat();    }    private void poolInit()    {        try        {            /** 加载配置文件 */ initClientGlobal();            /** 初始化空闲连接池 */ idleConnectionPool = new LinkedBlockingQueue<StorageClient1>();            /** 初始化忙碌连接池 */ // busyConnectionPool = new ConcurrentHashMap<StorageClient1, Object>();            TrackerClient trackerClient = new TrackerClient();            trackerServer = trackerClient.getConnection();            int flag = 0;            while (trackerServer == null && flag < 5)            {                System.out.println("[创建TrackerServer(createTrackerServer)][第" + flag + "次重建]");                flag++ ;                initClientGlobal();                trackerServer = trackerClient.getConnection();            }            // 测试 Tracker活跃情况            // ProtoCommon.activeTest(trackerServer.getSocket());            /** 往线程池中添加默认大小的线程 */ createTrackerServer();        }        catch (Exception e)        {            e.printStackTrace();            System.out.println("[FASTDFS初始化(init)--异常]");        }    }    public void createTrackerServer()    {        System.out.println("[创建TrackerServer(createTrackerServer)]");        TrackerServer trackerServer = null;        try        {            for (int i = 0; i < minPoolSize; i++ )            {                // 把client1添加到连接池                StorageServer storageServer = null;                StorageClient1 client1 = new StorageClient1(trackerServer, storageServer);                idleConnectionPool.add(client1);            }        }        catch (Exception e)        {            e.printStackTrace();            System.out.println("[创建TrackerServer(createTrackerServer)][异常:{}]");        }    }    public StorageClient1 checkout()    {        StorageClient1 client1 = idleConnectionPool.poll();        if (client1 == null)        {            if (idleConnectionPool.size() < maxPoolSize)            {                createTrackerServer();                try                {                    client1 = idleConnectionPool.poll(waitTimes, TimeUnit.SECONDS);                }                catch (Exception e)                {                    e.printStackTrace();                    System.out.println("[获取空闲连接(checkout)-error][error:获取连接超时:{}]");                }            }        }        // 添加到忙碌连接池        // busyConnectionPool.put(client1, obj);        System.out.println("[获取空闲连接(checkout)][获取空闲连接成功]");        return client1;    }    public void checkin(StorageClient1 client1)    {        System.out.println("[释放当前连接(checkin)]");        client1 = null;        if (idleConnectionPool.size() < minPoolSize)        {            createTrackerServer();        }    }    private void initClientGlobal()            throws Exception    {        ClientGlobal.init(FASTDFS_CONFIG);    }    public LinkedBlockingQueue<StorageClient1> getIdleConnectionPool()    {        return idleConnectionPool;    }    public long getMinPoolSize()    {        return minPoolSize;    }    public void setMinPoolSize(long minPoolSize)    {        if (minPoolSize != 0)        {            this.minPoolSize = minPoolSize;        }    }    public long getMaxPoolSize()    {        return maxPoolSize;    }    public void setMaxPoolSize(long maxPoolSize)    {        if (maxPoolSize != 0)        {            this.maxPoolSize = maxPoolSize;        }    }    public long getWaitTimes()    {        return waitTimes;    }    public void setWaitTimes(int waitTimes)    {        if (waitTimes != 0)        {            this.waitTimes = waitTimes;        }    }}
Controller 两个restful风格接口实现
@Api(value = "filenamager", tags = {"文件管理"})@RestController@RequestMapping("/filenamager/*")public class FileController {    Logger logger = LogManager.getLogger(FileController.class);    @Autowired    private FastDFSClient fastDFSClient;    @ApiOperation(value = "文件上传", notes = "文件上传")    @RequestMapping(value = "uploadFile",method = RequestMethod.POST)    public Map<String, Object> uploadFile(@RequestParam("uploadFile") MultipartFile filedata)    {        logger.info("lige1:" + filedata.toString());        Map<String, Object> m = new HashMap<String, Object>();        if (filedata != null && !filedata.isEmpty())        {            try            {                String path = fastDFSClient.uploadFile(filedata.getBytes(), filedata.getOriginalFilename());                m.put("code", Code.SUCCESS);                m.put("url", path);                m.put("msg", "上传成功");            }            catch (Exception e)            {                e.printStackTrace();                m.put("code", Code.FAIL);                m.put("msg", "上传失败");            }        }        else        {            m.put("code", Code.PARAMETER_LOST);            m.put("msg", "参数丢失");        }        return m;    }    @ApiOperation(value = "下载文件", notes = "下载文件")    @ApiImplicitParam(name = "path", value = "路径", required = true, dataType = "String")    @RequestMapping(value = "getFileByPath", method = RequestMethod.GET)    public void getFileByPath(HttpServletResponse response, String path)    {        try        {            // 判断文件是否存在            if (fastDFSClient.getFileInfo(path) != null)            {                byte[] buffer = fastDFSClient.downloadFile(path);                // 清空response                response.reset();                // 设置response的Header                response.addHeader("Content-Disposition",                        "attachment;filename=" + FileUtil.getOriginalFilename(path));                response.addHeader("Content-Length", "" + buffer.length);                // 通过文件流的形式写到客户端                OutputStream toClient = new BufferedOutputStream(response.getOutputStream());                response.setContentType("application/octet-stream");                toClient.write(buffer);                // 写完以后关闭文件流                toClient.flush();                toClient.close();            }        }        catch (IOException e)        {            e.printStackTrace();        }    }}
application.yml文件配置
server: port: 9010  tomcat: uri-encoding: UTF-8eureka: instance: hostname: eureka-server    prefer-ip-address: true  client: service-url: defaultZone: http://localhost:9001/eureka/spring: application: name: cloud-fastdfs-filemanager
fastdfs client相关配置就不贴了,直接从fast安装环境下取个client.conf改改就可以用了。

下面写下怎么通过httpclient 4.5来访问相关接口

public static void uploadFile(String filePath,String FileUploadURL) {    client = new DefaultHttpClient();    File targetFile = new File(filePath);    try {        if (targetFile == null || !targetFile.exists()) {            throw new FileNotFoundException();        }        MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();        multipartEntityBuilder                .addBinaryBody("uploadFile", targetFile)                .setMode(HttpMultipartMode.RFC6532);        HttpPost httpPost = new HttpPost(FileUploadURL);        httpPost.setEntity(multipartEntityBuilder.build());        HttpResponse httpResponse = client.execute(httpPost);        HttpEntity httpEntity =  httpResponse.getEntity();        String content = EntityUtils.toString(httpEntity);        System.out.println(content);    }    catch(Exception e)    {        e.printStackTrace();    }}

{"msg":"上传成功","code":"SUCCESS","url":"group1/M00/00/00/CgEDEFp_3eKASSzfAABEs-HwdPA11.xlsx"}

执行结果