一、添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--fastdfs-->
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
二、配置yml
server:
port: 6666
spring:
profiles:
active: dev
application:
name: API-SETTING
main:
allow-bean-definition-overriding: true
servlet:
# 文件大小配置
multipart:
max-file-size: 100MB
max-request-size: 100MB
http:
#最大连接数
maxTotal: 100
#并发数
defaultMaxPerRoute: 20
#创建连接的最长时间
connectTimeout: 1000
#从连接池中获取到连接的最长时间
connectionRequestTimeout: 500
#数据传输的最长时间
socketTimeout: 10000
#提交请求前测试连接是否可用
staleConnectionCheckEnabled: true
#https证书路径
keyStorePath: .keystore
#证书密码
keyStorepass: ehe.aaa.admin
fdfs:
tracker-list: # tracker地址,ip端口改一下
- 11.11.11.1:8080
so-timeout: 1501
connect-timeout: 601
thumb-image: # 缩略图
width: 200
height: 200
三、controller
@Api(value = "文件传输", tags = "文件传输")
@RequestMapping("/file")
public interface FileController {
@ApiOperation(value = "上传", notes = "上传")
@PostMapping("/upload")
ResponseInfo<String> upload(MultipartFile file) throws IOException;
@ApiOperation(value = "上传并返回文件路径和文件名", notes = "上传并返回文件路径和文件名")
@PostMapping("/upload/info")
ResponseInfo<Map<String, String>> uploadAndInfo(MultipartFile file) throws IOException;
@ApiOperation(value = "缩略图路径", notes = "缩略图路径")
@GetMapping("/thumbImagePath")
ResponseInfo<String> getThumbImagePath(@ApiParam(value = "文件路径", required = true) @RequestParam String fullPath);
@ApiOperation(value = "下载", notes = "下载")
@GetMapping(value = "/download", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
void download(@ApiParam(value = "文件路径", required = true) @RequestParam String fullPath, HttpServletResponse response) throws IOException;
@ApiOperation(value = "删除", notes = "删除")
@DeleteMapping("/delete")
void delete(@ApiParam(value = "文件路径", required = true) @RequestParam String fullPath);
@ApiOperation(value = "下载缩略图", notes = "下载缩略图")
@GetMapping(value = "/download/thunimage", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
void downloadThubImagePath(@ApiParam(value = "文件路径", required = true) @RequestParam String fullPath, HttpServletResponse response) throws IOException;
}
service
@Slf4j
@RestController
public class FileControllerImpl implements FileController {
@Autowired
private FastFileStorageClient storageClient;
@Autowired
private ThumbImageConfig thumbImageConfig;
private static final String META_DATA_NAME_FILE_NAME = "FILE_NAME";
@Autowired
private FileService fileService;
@Override
public ResponseInfo<String> upload(MultipartFile file) throws IOException {
Map<String, String> result = fileService.uploadFile(file);
return ResponseInfo.ofOk("上传成功!", result.get("uri"));
}
@Override
public ResponseInfo<Map<String, String>> uploadAndInfo(MultipartFile file) throws IOException {
Map<String, String> result = fileService.uploadFile(file);
return ResponseInfo.ofOk("上传成功!", result);
}
@Override
public ResponseInfo<String> getThumbImagePath(@RequestParam String fullPath) {
StorePath storePath = StorePath.parseFromUrl(fullPath);
return ResponseInfo.ofOk(HttpResponseStatus.SC_OK.getMessage(), thumbImageConfig.getThumbImagePath(storePath.getFullPath()));
}
@Override
public void download(@ApiParam(value = "文件路径", required = true) @RequestParam String fullPath, HttpServletResponse response) throws IOException {
StorePath storePath = StorePath.parseFromUrl(fullPath);
Set<MetaData> metaDataSet = storageClient.getMetadata(storePath.getGroup(), storePath.getPath());
String fileName = metaDataSet.stream().findFirst()
.filter(metaData -> META_DATA_NAME_FILE_NAME.equals(metaData.getName()))
.map(MetaData::getValue)
.orElse(FilenameUtils.getName(fullPath));
byte[] bytes = storageClient.downloadFile(storePath.getGroup(), storePath.getPath(), new DownloadByteArray());
response.reset();
response.setContentType("multipart/form-data;charset=UTF-8;");
fileName = new String(fileName.getBytes("gb2312"), "ISO8859-1");
response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
try (OutputStream outputStream = response.getOutputStream()) {
outputStream.write(bytes);
}
}
@Override
public void delete(@ApiParam(value = "文件路径", required = true) @RequestParam String fullPath) {
storageClient.deleteFile(fullPath);
}
@Override
public synchronized void downloadThubImagePath(String fullPath, HttpServletResponse response) throws IOException {
StorePath storePath = StorePath.parseFromUrl(fullPath);
String path = thumbImageConfig.getThumbImagePath(storePath.getFullPath());
this.download(path,response);
}
}
serviceimpl
@Service
public class FileServiceImpl implements FileService {
private static final Set<String> IMAGE_PREFIX_SET = Set.of("JPG", "JPEG", "PNG", "GIF", "BMP", "WBMP");
@Autowired
private FastFileStorageClient storageClient;
private static final String META_DATA_NAME_FILE_NAME = "FILE_NAME";
@Override
public Map<String, String> uploadFile(MultipartFile file) throws IOException {
String fileName = file.getOriginalFilename();
String filePrefix = FilenameUtils.getExtension(fileName);
StorePath storePath;
if (IMAGE_PREFIX_SET.contains(filePrefix.toUpperCase())) {
storePath = this.storageClient.uploadImageAndCrtThumbImage(file.getInputStream(), file.getSize(), filePrefix, Collections.singleton(new MetaData(META_DATA_NAME_FILE_NAME, fileName)));
} else {
storePath = this.storageClient.uploadFile(file.getInputStream(), file.getSize(), filePrefix, Collections.singleton(new MetaData(META_DATA_NAME_FILE_NAME, fileName)));
}
Map<String, String> result = new HashMap<>();
result.put("uri", storePath.getFullPath());
result.put("name", fileName);
return result;
}
}