FastDFS的理解及安装请参考:
理解:http://blog.youkuaiyun.com/juan0728juan/article/details/78673447
安装:http://blog.youkuaiyun.com/juan0728juan/article/details/78678458
这里介绍的是SpringBoot整合FastDFS实现上传文件的功能;
(1)在pom.xml中引入一个好心人在maven仓库中提交的fastdfs-java的客户端
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
<version>1.25.3-RELEASE</version>
</dependency>
(2)在application.yml中配置
# 分布式文件系统FDFS配置
fdfs:
soTimeout: 1500 #socket连接超时时长
connectTimeout: 600 #连接tracker服务器超时时长
resHost: 192.168.1.11
storagePort: 80
thumbImage: #缩略图生成参数,可选
width: 150
height: 150
trackerList: #TrackerList参数,支持多个,我这里只有一个,如果有多个在下方加- x.x.x.x:port
- 192.168.1.11:22122
spring:
http:
multipart:
max-file-size: 100MB # 最大支持文件大小
max-request-size: 100MB # 最大支持请求大小
(3)配置类(用于获取storage信息)
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class FdfsConfig {
@Value("${fdfs.resHost}")
private String resHost;
@Value("${fdfs.storagePort}")
private String storagePort;
public String getResHost() {
return resHost;
}
public void setResHost(String resHost) {
this.resHost = resHost;
}
public String getStoragePort() {
return storagePort;
}
public void setStoragePort(String storagePort) {
this.storagePort = storagePort;
}
}
(4)增加配置类(此类里面什么都不需要做,也可以把@Import和@EnableMBeanExport放在启动类上,我是感觉启动类上放太多东西不好看就增加了一个配置类)
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;
/**
* 导入FastDFS-Client组件
*/
@Configuration
@Import(FdfsClientConfig.class)//注解,就可以拥有带有连接池的FastDFS Java客户端了
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)// 解决jmx重复注册bean的问题
public class FdfsConfiguration {
}
(5)上传工具类
import java.io.IOException;
import java.io.InputStream;
import com.li.original.common.constant.GlobalConstants;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import com.github.tobato.fastdfs.domain.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
/**
* 工具类
*/
@Component
public class FastDFSClientWrapper {
@Autowired
private FastFileStorageClient storageClient;
@Autowired
private FdfsConfig fdfsConfig;
public String uploadFile(MultipartFile file) throws IOException {
StorePath storePath = storageClient.uploadFile((InputStream)file.getInputStream(),file.getSize(), FilenameUtils.getExtension(file.getOriginalFilename()),null);
return getResAccessUrl(storePath);
}
/**
* 封装文件完整URL地址
* @param storePath
* @return
*/
private String getResAccessUrl(StorePath storePath) {
String fileUrl = GlobalConstants.HTTP_PRODOCOL + fdfsConfig.getResHost() + ":" + fdfsConfig.getStoragePort() + "/" + storePath.getFullPath();
return fileUrl;
}
}
(6)控制类
import com.li.original.common.fdfs.FastDFSClientWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@Controller
@RequestMapping("/upload")
public class UploadController {
@Autowired
private FastDFSClientWrapper dfsClient;
@GetMapping("/")
public String index() {
return "upload/upload";
}
@PostMapping("/fdfs_upload")
public String fdfsUpload(@RequestParam("file") MultipartFile file,
RedirectAttributes redirectAttributes) {
if (file.isEmpty()) {
redirectAttributes.addFlashAttribute("message", "Please select a file to upload");
return "redirect:/upload/uploadStatus";
}
try {
String fileUrl= dfsClient.uploadFile(file);
redirectAttributes.addFlashAttribute("message",
"You successfully uploaded '" + fileUrl + "'");
} catch (IOException e) {
e.printStackTrace();
}
return "redirect:/upload/uploadStatus";
}
@GetMapping("/uploadStatus")
public String uploadStatus() {
return "upload/uploadStatus";
}
}
(7)upload.ftl(继承的freemark,放在template/upload下面,下面的uploadStatus.ftl也是)
<!DOCTYPE html>
<html>
<body>
<h1>Spring Boot file upload example</h1>
<form method="POST" action="fdfs_upload" enctype="multipart/form-data">
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
<input type="file" name="file" /><br/><br/>
<input type="submit" value="Submit" />
</form>
</body>
</html>
(8)uploadStatus.ftl
<!DOCTYPE html>
<html>
<body>
<h1>Spring Boot - Upload Status</h1>
<div>
<h2>${message}</h2>
</div>
</body>
</html>
(9)增加一个上传文件异常捕获类
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartException;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import javax.servlet.http.HttpServletRequest;
@ControllerAdvice//全局异常处理
public class GlobalExceptionHandler {
/**
* 捕获上传文件异常
* @param e
* @return
*/
//https://jira.spring.io/browse/SPR-14651
//4.3.5 supports RedirectAttributes redirectAttributes
@ExceptionHandler(MultipartException.class)
public ModelAndView handleError1(MultipartException e) {
ModelAndView mav = new ModelAndView();
mav.addObject("message", "上传文件异常");
mav.setViewName("upload/uploadStatus");
return mav;
}
}