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());
        }
    }
原文地址:https://www.cnblogs.com/naixin007/p/10207113.html