FastDFS部署參考這裏
FastDFS_Client使用
添加依賴
FastDFS_Client:項目地址
Simplemagic:項目地址
pom.xml
中添加:
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
<version>1.27.2</version>
</dependency>
<dependency>
<groupId>com.j256.simplemagic</groupId>
<artifactId>simplemagic</artifactId>
<version>1.16</version>
</dependency>
添加配置類
新建FastDFSConfig.java
@Configuration
@Import(FdfsClientConfig.class)
//解決jmx重複註冊bean的問題
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
public class FastDFSConfig {
// 導入依賴組件
}
修改配置文件
在application.properties
後面添加:
# 連接超時時長
fdfs.so-timeout = 1501
fdfs.connect-timeout = 601
# traker服務的訪問地址,有多個時用逗號隔開
fdfs.tracker-list = tracker1IP:tracker1Port,tracker2IP:tracker2Port
新建FastDFS工具類
新建FastDFSUtils.java
@Slf4j
@Component
public class FastDFSUtils {
@Autowired
private FastFileStorageClient fastFileStorageClient;
//文件上傳
public String uploadFile(MultipartFile file) throws Exception {
log.info("開始上傳文件至FastDFS:{}", file.getName());
byte[] bytes;
try {
bytes = file.getBytes();
} catch (IOException e) {
log.error("讀取文件錯誤");
throw new Exception("讀取文件錯誤");
}
//獲取源文件名稱
String originalFileName = file.getOriginalFilename();
//獲取文件後綴
String extension = originalFileName.substring(originalFileName.lastIndexOf(".") + 1);
//獲取文件大小
long fileSize = file.getSize();
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
StorePath storePath = fastFileStorageClient.uploadFile(byteArrayInputStream, fileSize, extension, null);
log.info("文件上傳至FastDFS成功path:{}", storePath.getFullPath());
return storePath.getFullPath();
}
//文件上傳(本地文件)
public String uploadFile(File file) throws Exception {
log.info("開始上傳文件至FastDFS:{}", file.getName());
byte[] bytes;
InputStream inputStream = null;
try {
inputStream = openInputStream(file);
bytes = IOUtils.toByteArray(inputStream, file.length());
} catch (IOException e) {
log.error("讀取文件錯誤");
//關閉輸入流
IOUtils.closeQuietly(inputStream);
throw new Exception("讀取文件錯誤");
}
//獲取源文件名稱
String fileName = file.getName();
//獲取文件後綴
String extension = fileName.substring(fileName.lastIndexOf(".") + 1);
//獲取文件大小
long fileSize = file.length();
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
StorePath storePath = fastFileStorageClient.uploadFile(byteArrayInputStream, fileSize, extension, null);
log.info("文件上傳至FastDFS成功path:{}", storePath.getFullPath());
//關閉輸入流
IOUtils.closeQuietly(inputStream);
return storePath.getFullPath();
}
//文件轉輸入流
public static FileInputStream openInputStream(File file) throws IOException {
if (file.exists()) {
if (file.isDirectory()) {
throw new IOException("文件" + file + "'是一個目錄");
}
if (!file.canRead()) {
throw new IOException("文件" + file + "無法讀取");
}
} else {
throw new FileNotFoundException("文件" + file + "不存在");
}
return new FileInputStream(file);
}
/**
* 文件下載
*
* @param fileUrl 示例:group1/M00/00/00/oYYBAF6ZsvCAaQzIAABdreSfEnY579.jpg
*/
public void downloadFile(String fileUrl, HttpServletResponse response) throws Exception {
//設置ContentType
response.setContentType(getContentType(fileUrl));
//設置keep-alive
response.setHeader("Connection", "keep-alive");
ServletOutputStream outputStream;
try {
//刷新緩衝
response.flushBuffer();
//獲取輸出流
outputStream = response.getOutputStream();
} catch (IOException e) {
log.error("獲取輸出流異常", e);
throw new Exception("獲取輸出流異常");
}
//解析url
StorePath storePath = StorePath.parseFromUrl(fileUrl);
//下載文件
DownloadFileStream downloadFileStream = new DownloadFileStream(outputStream);
fastFileStorageClient.downloadFile(storePath.getGroup(), storePath.getPath(), downloadFileStream);
//關閉輸出流
IOUtils.closeQuietly(outputStream);
}
/**
* 文件刪除
*
* @param fileUrl 示例:group1/M00/00/00/oYYBAF6ZsvCAaQzIAABdreSfEnY579.jpg
*/
public void deleteFile(String fileUrl) {
log.info("刪除FastFDS文件:{}", fileUrl);
fastFileStorageClient.deleteFile(fileUrl);
}
/**
* 下載文件時獲取ContentType
*
* @param fileName 文件名中包含後綴即可
*/
public String getContentType(String fileName) {
ContentInfo contentInfo = ContentInfoUtil.findExtensionMatch(fileName);
if (contentInfo == null) {
return null;
}
return contentInfo.getMimeType();
}
}
Controller參考代碼
@Resource
FastDFSUtils fastDFSUtils;
//上傳文件,返回示例:group1/M00/00/00/oYYBAF6ZsvCAaQzIAABdreSfEnY579.jpg
@ApiOperation(value = "up", notes = "")
@RequestMapping(value = "/up", method = {RequestMethod.POST})
public String up(MultipartFile file) {
try {
return fastDFSUtils.uploadFile(file);
} catch (Exception e) {
e.printStackTrace();
}
return "fail";
}
//下載文件,參數示例:group1/M00/00/00/oYYBAF6ZsvCAaQzIAABdreSfEnY579.jpg
@ApiOperation(value = "down", notes = "")
@RequestMapping(value = "/down", method = {RequestMethod.GET})
public void down(String url, HttpServletResponse response) {
try {
try {
fastDFSUtils.downloadFile(url, response);
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
使用token防盜鏈
FastDFS服務器開啓token防盜鏈,參考這裏
開啓token後,通過client訪問文件不受影響,通過nginx訪問需要添加token參數
添加依賴
在pom.xml
中添加:
<dependency>
<groupId>net.oschina.zcx7878</groupId>
<artifactId>fastdfs-client-java</artifactId>
<version>1.27.0.0</version>
</dependency>
修改配置文件
在application.properties
後面添加:
# 開啓token
fdfs.http.anti_steal_token = true
# 服務器配置的secret key
fdfs.http.secret_key = 123456
# 通過nginx訪問fastDFS的地址
fdfs.web-server-url = http://yourIp:port/files/
FastDFS工具類
生成token參考代碼如下:
在FastDFSUtils.java
中添加:
@Value("${fdfs.web-server-url}")
private String fastDfsUrl;
@Value("${fdfs.http.secret_key}")
private String fastDfsKey;
/**
* 獲取帶有token的訪問地址
*
* @param fileUrl 示例:group1/M00/00/00/L2ZUml6QisqAUJE3AIOPO1HT6Bo274.mp4
* @return java.lang.String 示例:http://yourIp:port/files/group1/M00/00/00/L2ZUml6QisqAUJE3AIOPO1HT6Bo274.mp4?token=e9a6ae7f1ecca6fed51e248c6a10d3bc&ts=1589361883
*/
public String getTokenUrl(String fileUrl) throws Exception {
String path = StorePath.parseFromUrl(fileUrl).getPath();
//時間戳 單位爲秒
int ts = (int) (System.currentTimeMillis() / 1000);
String token;
try {
token = ProtoCommon.getToken(path, ts, fastDfsKey);
} catch (Exception e) {
log.error("獲取token異常", e);
throw new Exception("FastDFS獲取token異常");
}
return fastDfsUrl + fileUrl + "?token=" + token + "&ts=" + ts;
}