只粘贴重要代码,其余代码看源码地址!

1、pom.xml 依赖。FastDFS 我们使用 com.github.tobato 封装好的 fastdfs-client,同时必须加上 commons-fileupload 依赖,否则报错:ClassNotFoundException DiskFileItemFactory

<?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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.study</groupId>
    <artifactId>study-fastdfs</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
    </parent>

    <!-- 统一配置版本 -->
    <properties>
        <fastdfs.version>1.27.2</fastdfs.version>
        <commons-fileupload.version>1.4</commons-fileupload.version>
        <fastjson.version>1.2.75</fastjson.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- fastdfs 依赖:https://mvnrepository.com/artifact/com.github.tobato/fastdfs-client -->
        <dependency>
            <groupId>com.github.tobato</groupId>
            <artifactId>fastdfs-client</artifactId>
            <version>${fastdfs.version}</version>
        </dependency>

        <!-- 要加上 commons-fileupload,否则报错:ClassNotFoundException DiskFileItemFactory-->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>${commons-fileupload.version}</version>
        </dependency>

        <!-- lombok 依赖 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <!-- 阿里巴巴 fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>${fastjson.version}</version>
        </dependency>
    </dependencies>

</project>

 

2、controller 层

package com.study.controller;

import com.alibaba.fastjson.JSON;
import com.study.message.ResponseMsg;
import com.study.service.FileService;
import com.study.util.NetworkUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.net.URL;

/**
 * @author biandan
 * @description 文件上传
 * @signature 让天下没有难写的代码
 * @create 2021-06-09 上午 12:07
 */
@RestController
@RequestMapping("/file")
public class FastDFSController {

    @Autowired
    private FileService fileService;

    /**
     * 文件上传
     *
     * @param request
     * @return
     */
    @RequestMapping("/upload")
    public ResponseMsg upload(HttpServletRequest request) {
        //单纯的获取一些信息,与业务逻辑无关。如果想要这些信息搞事情,也是可以的
        try {
            String referer = request.getHeader("Referer");
            System.out.println("referer=" + referer);

            String ipAddress = NetworkUtil.getIpAddress(request);
            System.out.println("ipAddress=" + ipAddress);

            URL url = new URL(referer);
            String host = url.getHost();
            System.out.println("host=" + host);
        } catch (Exception e) {
            e.printStackTrace();
        }
        Long startTime = System.currentTimeMillis();//记录开始时间
        ResponseMsg responseMsg = fileService.upload(request);
        Long endTime = System.currentTimeMillis();//记录结束时间
        System.out.println("上传文件共花费时间:" + ((endTime - startTime) / 1000) + " 秒");
        System.out.println("responseMsg=" + JSON.toJSONString(responseMsg));
        return responseMsg;
    }

}

 

3、实现类

package com.study.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.study.entity.FileResponseEntity;
import com.study.message.ResponseMsg;
import com.study.service.FileService;
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.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @author biandan
 * @description
 * @signature 让天下没有难写的代码
 * @create 2021-06-09 上午 12:17
 */
@Service
public class FileServiceImpl implements FileService {

    //FastDFS 客户端
    @Autowired(required = false)
    private FastFileStorageClient fastFileStorageClient;

    //使用的组,这里默认是 group1
    @Value("${fastdfs.group:group1}")
    private String group;

    //访问的域名
    @Value("${fastdfs.domain}")
    private String domain;


    /**
     * 上传文件
     *
     * @param request
     * @return
     */
    @Override
    public ResponseMsg upload(HttpServletRequest request) {
        ResponseMsg responseMsg = new ResponseMsg();
        responseMsg.setCode("-1");
        responseMsg.setMessage("upload file error!");
        try {
            List<FileResponseEntity> list = dealWithFile(request);
            if (!CollectionUtils.isEmpty(list)) {
                responseMsg.setData(list);
                responseMsg.setCode("0");
                responseMsg.setMessage("success");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return responseMsg;
    }

    /**
     * 处理文件
     *
     * @param request
     * @return
     */
    private List<FileResponseEntity> dealWithFile(HttpServletRequest request) throws Exception {
        List<FileResponseEntity> list = new ArrayList<>();
        //将上下文的请求给 CommonsMultipartResolver (多部分解析器)
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
        //判断 form 表单中是否有多文件 enctype="multipart/form-data"
        if (multipartResolver.isMultipart(request)) {
            //将请求 request 变成多部分 request
            MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
            //获取 multipartRequest 所有文件名
            Iterator iterator = multipartRequest.getFileNames();
            while (iterator.hasNext()) {
                //一次性遍历所有文件
                MultipartFile file = multipartRequest.getFile(iterator.next().toString());
                if (null != file && !file.isEmpty()) {
                    FileResponseEntity responseEntity = new FileResponseEntity();
                    //使用 FastDFS 客户端上传文件
                    StorePath storePath = fastFileStorageClient.uploadFile(group, file.getInputStream(), file.getSize(), getFileExt(file.getOriginalFilename()));
                    System.out.println("storePath=" + JSON.toJSONString(storePath));
                    responseEntity.setOriginalName(file.getOriginalFilename());
                    //拼接完整路径
                    String fullPath = domain + storePath.getFullPath();
                    responseEntity.setTargetName(StringUtils.right(fullPath, fullPath.length() - fullPath.lastIndexOf("/") - 1));
                    responseEntity.setFullPath(fullPath);

                    list.add(responseEntity);
                }
            }
        }
        return list;
    }

    /**
     * 获取文件扩展名
     *
     * @param fileName
     * @return
     */
    private String getFileExt(String fileName) {
        String extName = "";
        if (StringUtils.isNotBlank(fileName) && fileName.lastIndexOf(".") != -1) {
            extName = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length());
        }
        return extName;
    }
}

4、解决 JMX 重复注册 Bean 的问题

package com.study.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;

/**
 * @author biandan
 * @description
 * @signature 让天下没有难写的代码
 * @create 2021-06-09 上午 1:14
 */
@Configuration
@Import(FdfsClientConfig.class)
// 处理 JMX 重复注册 Bean 的问题
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
public class FastDfsConfig {

}

 

5、解决跨域请求问题

package com.study.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

/**
 * @author biandan
 * @description 解决跨域
 * @signature 让天下没有难写的代码
 * @create 2021-06-09 上午 11:08
 */
@Configuration
public class CrossConfiguration {

    @Bean
    public CorsFilter corsFilter() {
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        final CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true); // 允许cookies跨域
        config.addAllowedOrigin("*");// #允许向该服务器提交请求的URI,*表示全部允许,在SpringMVC中,如果设成*,会自动转成当前请求头中的Origin
        config.addAllowedHeader("*");// #允许访问的头信息,*表示全部
        config.setMaxAge(18000L);// 预检请求的缓存时间(秒),即在这个时间段里,对于相同的跨域请求不会再预检了
        config.addAllowedMethod("*");// 允许提交请求的方法,*表示全部允许
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}

 

6、前端测试代码,需要引入 jquery.min.js  (直接从 IDEA 里使用浏览器打开即可进入测试页面!)

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>FastDFS分布式文件服务器</title>
    <script src="js/jquery.min.js"></script>
    <script type="text/javascript">

        var baseUrl = "http://127.0.0.1/";

        //文件上传接口
        function uploadFile() {
            var formData = new FormData();
            formData.append("file", $("#upload")[0].files[0]);
            var uploadPath = baseUrl + "file/upload/";
            $.ajax({
                url: uploadPath,
                type: 'POST',
                data: formData,
                xhrFields: {
                    'Access-Control-Allow-Origin': '*',
                    withCredentials: true
                },
                contentType: false,
                processData: false,
                beforeSend: function () {
                    console.log("正在上传,请稍候...");
                },
                success: function (data) {
                    console.log("结果:" + JSON.stringify(data));
                    $("#resultArea").val(JSON.stringify(data));
                    if (data.code === '0') {
                        $("#opResult").text("");
                        $("#opResult").css("color", "blue");
                        $("#opResult").text("操作成功!");
                    } else {
                        $("#opResult").text("");
                        $("#opResult").css("color", "red");
                        $("#opResult").text("操作失败!");
                    }
                },
                error: function (data) {
                    console.log("结果:" + JSON.stringify(data));
                    $("#resultArea").val(JSON.stringify(data));
                    if (data.code === '0') {
                        $("#opResult").text("");
                        $("#opResult").css("color", "blue");
                        $("#opResult").text("操作成功!");
                    } else {
                        $("#opResult").text("");
                        $("#opResult").css("color", "red");
                        $("#opResult").text("操作失败!");
                    }
                }
            });
        }

    </script>

</head>
<body style="width: 960px;margin:0px 150px;">
<h1>FastDFS分布式文件上传</h1>
<br>

<div>
    <input id="upload" type="file" name="file" value="选择文件"/>
    <input id="materiel" type="hidden" name="materiel" value="">
    <button onclick="uploadFile()">上传文件</button>
</div>
<br><br>

<span>结果:</span><span id="opResult"></span><br>
<textarea id="resultArea" cols="120" rows="6"></textarea><br><br>

</body>
</html>

7、application.yml 配置

server:
  port: 80

# 将SpringBoot项目作为单实例部署调试时,不需要注册到注册中心
eureka:
  client:
    fetch-registry: false
    register-with-eureka: false

spring:
  application:
    name: fastdfs-server

  # servlet 相关配置
  # SpringBoot 1.5版本是spring.http.multipart
  # SpringBoot 2.0版本是spring.servlet.multipart
  servlet:
    multipart:
      max-file-size: 50MB # 最大文件限制大小,默认1M
      max-request-size: 50MB #最大请求大小,默认10M
      enabled: true

# 分组的配置
fastdfs:
  group: group1
  domain: http://file.study.com/

# 分布式文件系统 FastDFS 配置
fdfs:
  so-timeout: 100000 #读取时间
  connect-timeout: 100000 # 连接超时时间
  tracker-list: # tracker 服务配置列表
    - 192.168.0.105:22122

  # 连接池配置
  pool:
    #从连接池中借出的最大数目
    max-total: 1000
    #取连接时的最大等待毫秒数
    max-wait-millis: 600000

 

OK,启动测试。

springboot kerberos 认证 hdfs hbase springboot hdfs整合_fastdfs-client

后台输出

springboot kerberos 认证 hdfs hbase springboot hdfs整合_spring_02