zoukankan      html  css  js  c++  java
  • FastDFS图片服务器实现图片上传

    一、传统使用

    1.将fastdfs_client.jar导入工程

    2.加载配置文件(如conf.properties),配置文件中的内容就是tracker服务的地址。

    配置文件内容:tracker_server=192.168.25.133:22122

    3.把commons-io、fileupload 的jar包添加到工程中

    4.页面代码

     

    页面使用的是KindEditor的多图片上传插件

    KindEditor 4.x 文档:http://kindeditor.net/doc.php

    参数:MultiPartFile uploadFile

    返回值:

    5、spring文件配置多媒体解析器

    <!-- 定义文件上传解析器 -->
        <bean id="multipartResolver"
            class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
            <!-- 设定默认编码 -->
            <property name="defaultEncoding" value="UTF-8"></property>
            <!-- 设定文件上传的最大值5MB,5*1024*1024 -->
            <property name="maxUploadSize" value="5242880"></property>
        </bean>

    6、上传代码(kindeditor对text/plain返回类型支持最好,如果返回json不兼容改为返回string)

    @Controller
    public class PictureController {
        @Value("${IMAGE_SERVER_URL}")
        private String IMAGE_SERVER_URL;
    
        @RequestMapping("/pic/upload")
        @ResponseBody
        public Map fileUpload(MultipartFile uploadFile) {
            try {
                //1、取文件的扩展名
                String originalFilename = uploadFile.getOriginalFilename();
                String extName = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
                //2、创建一个FastDFS的客户端
                FastDFSClient fastDFSClient = new FastDFSClient("classpath:resource/client.conf");
                //3、执行上传处理
                String path = fastDFSClient.uploadFile(uploadFile.getBytes(), extName);
                //4、拼接返回的url和ip地址,拼装成完整的url
                String url = IMAGE_SERVER_URL + path;
                //5、返回map
                Map result = new HashMap<>();
                result.put("error", 0);
                result.put("url", url);
                return result;
            } catch (Exception e) {
                e.printStackTrace();
                //5、返回map
                Map result = new HashMap<>();
                result.put("error", 1);
                result.put("message", "图片上传失败");
                return result;
            }
        }
    }

    二、SpringBoot使用FastDFS

    1.新建viuman-upload微服务。pom.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <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/xsd/maven-4.0.0.xsd">
        <parent>
            <artifactId>viuman</artifactId>
            <groupId>com.viuman</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>viuman-upload</artifactId>
    
        <dependencies>
            <dependency>
                <groupId>com.viuman</groupId>
                <artifactId>viuman-common</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>com.github.tobato</groupId>
                <artifactId>fastdfs-client</artifactId>
                <version>1.26.2</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
            </dependency>
        </dependencies>
    </project>

    2.application.yml

    server:
      port: 8082
    spring:
      application:
        name: upload
      servlet:
        multipart:
          max-file-size: 5MB # 限制文件上传的大小
    # Eureka
    eureka:
      client:
        service-url:
          defaultZone: http://127.0.0.1:10086/eureka
      instance:
        lease-renewal-interval-in-seconds: 5 # 每隔5秒发送一次心跳
        lease-expiration-duration-in-seconds: 10 # 10秒不发送就过期
        prefer-ip-address: true
        ip-address: 127.0.0.1
        instance-id: ${spring.application.name}:${server.port}
    # FastDFS
    fdfs:
      so-timeout: 1501
      connect-timeout: 601
      thumb-image: # 缩略图
         60
        height: 60
      tracker-list: # tracker地址
        - tracker.viuman.com:22122
    IMAGE_SERVER_DOMAIN: http://image.viuman.com/

    3.启动类

    package com.viuman;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    
    @SpringBootApplication
    @EnableDiscoveryClient
    public class UploadApplication {
        public static void main(String[] args) {
            SpringApplication.run(UploadApplication.class);
        }
    }

    4.修改网关微服务的application.yml。忽略路由上传微服务

    zuul:
      prefix: /api # 添加路由前缀
      retryable: true
      routes:
        item-service: /item/** #将商品微服务映射到/item/**
      ignored-services: upload #忽略路由该服务

    5.创建Cors跨域配置类。详见https://www.cnblogs.com/naixin007/p/10420684.html

    6.引入fdfs配置类

    package com.viuman.config;
    
    import com.github.tobato.fastdfs.FdfsClientConfig;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.EnableMBeanExport;
    import org.springframework.context.annotation.Import;
    import org.springframework.jmx.support.RegistrationPolicy;
    
    @Configuration
    @Import(FdfsClientConfig.class)
    //解决jmx重复注册bean的问题
    @EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
    public class FastClientImporter {
    }

    7.service层上传代码

    package com.viuman.upload.service.impl;
    
    import com.github.tobato.fastdfs.domain.StorePath;
    import com.github.tobato.fastdfs.domain.ThumbImageConfig;
    import com.github.tobato.fastdfs.service.FastFileStorageClient;
    import com.viuman.entity.Status;
    import com.viuman.exception.BusinessException;
    import com.viuman.upload.service.UploadService;
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Service;
    import org.springframework.web.multipart.MultipartFile;
    
    import javax.imageio.ImageIO;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import java.util.Arrays;
    import java.util.List;
    
    @Service
    public class UploadServiceImpl implements UploadService {
        @Autowired
        private FastFileStorageClient storageClient;
        @Autowired
        private ThumbImageConfig thumbImageConfig;
    
        @Value("${IMAGE_SERVER_DOMAIN}")
        private String IMAGE_SERVER_DOMAIN;
    
        //支持的文件类型
        List<String> suffixes = Arrays.asList("image/png", "image/jpeg");
    
        @Override
        public String upload(MultipartFile file) {
            if (null == file) {
                throw new BusinessException(Status.PARAM_LACK_ERROR);
            }
            if (!suffixes.contains(file.getContentType())) {
                throw new BusinessException(Status.PARAM_ILLEGAL_ERROR.setMsg("文件类型不支持"));
            }
            try {
                BufferedImage image = ImageIO.read(file.getInputStream());
                if (null == image) {
                    throw new BusinessException(Status.PARAM_ILLEGAL_ERROR.setMsg("文件内容不符合要求"));
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
    
            StorePath storePath = null;
            String extension = StringUtils.substringAfterLast(file.getOriginalFilename(), ".");
            try {
                storePath = storageClient.uploadImageAndCrtThumbImage(file.getInputStream(),
                        file.getSize(), extension, null);
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (null == storePath || StringUtils.isBlank(storePath.getFullPath())) {
                throw new BusinessException(Status.REMOTE_ERROR.setMsg("上传失败"));
            }
    
            String url = IMAGE_SERVER_DOMAIN + storePath.getFullPath();
            return url;
        }
    }

    8.上传返回结果

    原图路径:http://image.viuman.com/group1/M00/00/00/rBHRQl2UbEWAWsRwAAFWAkILswQ447.png

    缩略图路径:http://image.viuman.com/group1/M00/00/00/rBHRQl2UbEWAWsRwAAFWAkILswQ447_60x60.png

     9.删除文件

        /**
         * 删除文件
         * @param fileUrl 文件访问地址
         * @return
         */
        public void deleteFile(String fileUrl) {
            if (StringUtils.isEmpty(fileUrl)) {
                return;
            }
            try {
                StorePath storePath = StorePath.praseFromUrl(fileUrl);
                storageClient.deleteFile(storePath.getGroup(), storePath.getPath());
            } catch (FdfsUnsupportStorePathException e) {
                logger.warn(e.getMessage());
            }
        }
  • 相关阅读:
    CF869E The Untended Antiquity 解题报告
    Walk 解题报告
    CF911F Tree Destruction 解题报告
    P4397 [JLOI2014]聪明的燕姿
    洛谷 P2329 [SCOI2005]栅栏 解题报告
    洛谷 P3747 [六省联考2017]相逢是问候 解题报告
    set-erase
    set-empty
    set-empty
    set-end
  • 原文地址:https://www.cnblogs.com/naixin007/p/10207113.html
Copyright © 2011-2022 走看看