使用FastDFS進行檔案上傳下載下傳
導航
- 使用FastDFS進行檔案上傳下載下傳
-
- 一. 準備
-
- 1.1 引入pom依賴
- 1.2 在resources/application.yml中配置:
- 1.3 引入FastDFS相關的config
- 二. 上傳
-
- 2.1 測試FastDFS的相關代碼
- 2.2 改造業務代碼
- 三. 下載下傳
-
- 3.1 Client
- 3.2 上傳、下載下傳、删除等相關Api
一. 準備
1.1 引入pom依賴
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
<version>${fastDFS.clent.version}</version>
</dependency>
在SpringBoot内可不定義版本号,跟随SpringBoot
1.2 在resources/application.yml中配置:
fdfs:
so-timeout:1501 # 讀取逾時時間
connect-timeout: 601 #連接配接逾時時間
thumb-image: #縮略圖
width: 60
height: 60
tracker-list: # tracker位址: 你的虛拟機伺服器位址+端口 (預設是22122)
- 192.168.56.101:22122
1.3 引入FastDFS相關的config
@Configuration
@Import(FdfsClientConfig.class)
//解決jmx重複注冊bean的問題
@EnableMBeanExport(registration=RegistrationPolicy.IGNORE_EXISTING)
public class FastClientImporter{}
這裡不需要寫代碼,因為@Import引入的配置就是别人已經寫好的代碼,我們就可以不用寫東西了;第二個是為了防止Bean重複注入;
二. 上傳
2.1 測試FastDFS的相關代碼
@SpringBootTest
@RunWith(SpringRunner.class)
public class FastDFSTest{
@Autowired
private FastFileStorageClient storageClient;
@Autowired
private ThumbImageConfig thumbImageConfig;
@Test
public void testUpload() throws FileNotFoundException{
//要上傳的檔案
File file=new File("C:\\USERS\\iamge.jpg")
//上傳并儲存圖檔,參數: 1-上傳的檔案流 2-檔案的大小 3-檔案的字尾 4-可以不管他
StorePath storePath =this.storageClient.uploadFile(new FileInputStream(file),file.length(),"jpg",null);
//帶分組的路徑
System.out.println(storePath.getFullPath()); //group1/M00/00/00/xxxx.jpg
//不帶分組的路徑
System.out.println(storePath.getPath()); //M00/00/00/xxxx.jpg
//我們在浏覽器内通路: 192.168.56.101/group1/M00/00/00/xxxxx.jpg
//如果配置了域名,則可以通過域名通路,比如:image.baidu.com/group1/M00/00/00/xxxxx.jpg
}
//測試生成縮略圖
@Test
public void testUploadAndCreateThumb() throws FileNotFoundException{
File file=new File("C:\\Users\\joedy\\Pictures\\xbx1.jpg")
//上傳并且生成縮略圖
StorePath storePath=this.storageClient.uploadImageAndCrtThumbImage(
new FileInputStream(file),file.length(),"jpg",null);
//帶分組的路徑
System.out.println(storePath.getFullPath());
//不帶分組的路徑
System.out.println(storePath.getPath());
//擷取縮略圖路徑
String path=thumbImageConfig.getThumbImagePath(storePath.getPath());
System.out.println(path);
}
}
2.2 改造業務代碼
@Service
public class UploadService{
private static final List<String> CONTENT_TYPES=Arrays.asList("image/gif","image/jpeg");
private static final Logger LOGGER= LoggerFactory.getLogger(UploadService.class);
@Autowired
private FastFileStorageClient storageClient;
public String uploadImage(MutipartFile file){
String originalFilename=file.getOriginalFilename();
//校驗檔案類型
String contentType=file.getContentType();
if(!CONTENT_TYPES.contains(contentType)){
LOGGER.info("檔案類型不合法:{}",originalFilename); //這裡的第二個參數會自動進入{}内
return null;
}
//儲存到伺服器
//file.transferTo(new File("C:\\image\\"+originalFilename)); 這裡是儲存到本地磁盤,這裡不用這個。
String ext=StringUtils.substringAfterLast(originalFilename,".");
StorePath storePath=this.storageClient.uploadFile(file.getInputStream(),file.getSize(),ext,null);
//傳回url,進行回顯
//return "http://image.baidu.com/" + originalFilename;
return "http://image.baidu.com"+ storePath.getFullPath();
}catch(IOException e){
LOGGER.info("伺服器内部錯誤:"+originalFilename);
e.printStackTrace();
}
return null;
}
三. 下載下傳
3.1 Client
import com.cdmtc.config.ErrorCode;
import com.cdmtc.config.FastDFSException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.csource.common.MyException;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.FileInfo;
import org.csource.fastdfs.ProtoCommon;
import org.csource.fastdfs.StorageClient1;
import org.csource.fastdfs.TrackerServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* FastDFS Java API. 檔案上傳下載下傳主類.
*/
public class FastDFSClient {
private static class SingletonHolder{
/**
* 靜态初始化器,由JVM來保證線程安全
*/
private static FastDFSClient instance = new FastDFSClient();
}
/**
* 路徑分隔符
*/
public static final String SEPARATOR = "/";
/**
* Point
*/
public static final String POINT = ".";
/**
* ContentType
*/
public static final Map<String, String> EXT_MAPS = new HashMap<>();
/**
* org.slf4j.Logger
*/
private static Logger logger = LoggerFactory.getLogger(FastDFSClient.class);
/**
* 檔案名稱Key
*/
private static final String FILENAME = "filename";
/**
* 檔案最大的大小
*/
private int maxFileSize = 100 * 1000 * 1000;
public FastDFSClient() {
initExt();
}
public static FastDFSClient getInstance(){
return SingletonHolder.instance;
}
private void initExt() {
// image
EXT_MAPS.put("png", "image/png");
EXT_MAPS.put("gif", "image/gif");
EXT_MAPS.put("bmp", "image/bmp");
EXT_MAPS.put("ico", "image/x-ico");
EXT_MAPS.put("jpeg", "image/jpeg");
EXT_MAPS.put("jpg", "image/jpeg");
// 壓縮檔案
EXT_MAPS.put("zip", "application/zip");
EXT_MAPS.put("rar", "application/x-rar");
// doc
EXT_MAPS.put("pdf", "application/pdf");
EXT_MAPS.put("ppt", "application/vnd.ms-powerpoint");
EXT_MAPS.put("xls", "application/vnd.ms-excel");
EXT_MAPS.put("xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
EXT_MAPS.put("pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation");
EXT_MAPS.put("doc", "application/msword");
EXT_MAPS.put("doc", "application/wps-office.doc");
EXT_MAPS.put("docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
EXT_MAPS.put("txt", "text/plain");
// 音頻
EXT_MAPS.put("mp4", "video/mp4");
EXT_MAPS.put("flv", "video/x-flv");
}
/**
* MultipartFile 上傳檔案
*
* @param file MultipartFile
* @return 傳回上傳成功後的檔案路徑
*/
public String uploadFileWithMultipart(MultipartFile file) throws FastDFSException {
return upload(file, null);
}
/**
* MultipartFile 上傳檔案
*
* @param file MultipartFile
* @param descriptions 檔案描述
* @return 傳回上傳成功後的檔案路徑
*/
public String uploadFileWithMultipart(MultipartFile file, Map<String, String> descriptions) throws FastDFSException {
return upload(file, descriptions);
}
/**
* 根據指定的路徑上傳檔案
*
* @param filepath 檔案路徑
* @return 傳回上傳成功後的檔案路徑
*/
public String uploadFileWithFilepath(String filepath) throws FastDFSException {
return upload(filepath, null);
}
/**
* 根據指定的路徑上傳檔案
*
* @param filepath 檔案路徑
* @param descriptions 檔案描述
* @return 傳回上傳成功後的檔案路徑
*/
public String uploadFileWithFilepath(String filepath, Map<String, String> descriptions) throws FastDFSException {
return upload(filepath, descriptions);
}
/**
* 上傳base64檔案
*
* @param base64 檔案base64
* @return 傳回上傳成功後的檔案路徑
*/
public String uploadFileWithBase64(String base64) throws FastDFSException {
return upload(base64, null, null);
}
/**
* 上傳base64檔案
*
* @param base64 檔案base64
* @param filename 檔案名
* @return 傳回上傳成功後的檔案路徑
*/
public String uploadFileWithBase64(String base64, String filename) throws FastDFSException {
return upload(base64, filename, null);
}
/**
* 上傳base64檔案
*
* @param base64 檔案base64
* @param filename 檔案名
* @param descriptions 檔案描述資訊
* @return 傳回上傳成功後的檔案路徑
*/
public String uploadFileWithBase64(String base64, String filename, Map<String, String> descriptions) throws FastDFSException {
return upload(base64, filename, descriptions);
}
/**
* 使用 MultipartFile 上傳
*
* @param file MultipartFile
* @param descriptions 檔案描述資訊
* @return 檔案路徑
* @throws FastDFSException file為空則抛出異常
*/
public String upload(MultipartFile file, Map<String, String> descriptions) throws FastDFSException {
if(file == null || file.isEmpty()){
throw new FastDFSException(ErrorCode.FILE_ISNULL.CODE, ErrorCode.FILE_ISNULL.MESSAGE);
}
String path = null;
try {
path = upload(file.getInputStream(), file.getOriginalFilename(), descriptions);
} catch (IOException e) {
e.printStackTrace();
throw new FastDFSException(ErrorCode.FILE_ISNULL.CODE, ErrorCode.FILE_ISNULL.MESSAGE);
}
return path;
}
/**
* 根據指定的路徑上傳
*
* @param filepath 檔案路徑
* @param descriptions 檔案描述
* @return 檔案路徑
* @throws FastDFSException 檔案路徑為空則抛出異常
*/
public String upload(String filepath, Map<String, String> descriptions) throws FastDFSException {
if(StringUtils.isBlank(filepath)){
throw new FastDFSException(ErrorCode.FILE_PATH_ISNULL.CODE, ErrorCode.FILE_PATH_ISNULL.MESSAGE);
}
File file = new File(filepath);
String path = null;
try {
InputStream is = new FileInputStream(file);
// 擷取檔案名
filepath = toLocal(filepath);
String filename = filepath.substring(filepath.lastIndexOf("/") + 1);
path = upload(is, filename, descriptions);
} catch (FileNotFoundException e) {
e.printStackTrace();
throw new FastDFSException(ErrorCode.FILE_NOT_EXIST.CODE, ErrorCode.FILE_NOT_EXIST.MESSAGE);
}
return path;
}
/**
*
* 上傳base64檔案
*
* @param base64
* @param filename 檔案名
* @param descriptions 檔案描述資訊
* @return 檔案路徑
* @throws FastDFSException base64為空則抛出異常
*/
public String upload(String base64, String filename, Map<String, String> descriptions) throws FastDFSException {
if(StringUtils.isBlank(base64)){
throw new FastDFSException(ErrorCode.FILE_ISNULL.CODE, ErrorCode.FILE_ISNULL.MESSAGE);
}
return upload(new ByteArrayInputStream(Base64.decodeBase64(base64)), filename, descriptions);
}
/**
* 上傳通用方法
*
* @param is 檔案輸入流
* @param filename 檔案名
* @param descriptions 檔案描述資訊
* @return 組名+檔案路徑,如:group1/M00/00/00/wKgz6lnduTeAMdrcAAEoRmXZPp870.jpeg
* @throws FastDFSException
*/
public String upload(InputStream is, String filename, Map<String, String> descriptions) throws FastDFSException {
if(is == null){
throw new FastDFSException(ErrorCode.FILE_ISNULL.CODE, ErrorCode.FILE_ISNULL.MESSAGE);
}
try {
if(is.available() > maxFileSize){
throw new FastDFSException(ErrorCode.FILE_OUT_SIZE.CODE, ErrorCode.FILE_OUT_SIZE.MESSAGE);
}
} catch (IOException e) {
e.printStackTrace();
}
filename = toLocal(filename);
// 傳回路徑
String path = null;
// 檔案描述
NameValuePair[] nvps = null;
List<NameValuePair> nvpsList = new ArrayList<>();
// 檔案名字尾
String suffix = getFilenameSuffix(filename);
// 檔案名
if (StringUtils.isNotBlank(filename)) {
nvpsList.add(new NameValuePair(FILENAME, filename));
}
// 描述資訊
if (descriptions != null && descriptions.size() > 0) {
descriptions.forEach((key, value) -> {
nvpsList.add(new NameValuePair(key, value));
});
}
if (nvpsList.size() > 0) {
nvps = new NameValuePair[nvpsList.size()];
nvpsList.toArray(nvps);
}
TrackerServer trackerServer = TrackerServerPool.borrowObject();
StorageClient1 storageClient = new StorageClient1(trackerServer, null);
try {
// 讀取流
byte[] fileBuff = new byte[is.available()];
is.read(fileBuff, 0, fileBuff.length);
// 上傳
path = storageClient.upload_file1(fileBuff, suffix, nvps);
if(StringUtils.isBlank(path)) {
throw new FastDFSException(ErrorCode.FILE_UPLOAD_FAILED.CODE, ErrorCode.FILE_UPLOAD_FAILED.MESSAGE);
}
if (logger.isDebugEnabled()) {
logger.debug("upload file success, return path is {}", path);
}
} catch (IOException e) {
e.printStackTrace();
throw new FastDFSException(ErrorCode.FILE_UPLOAD_FAILED.CODE, ErrorCode.FILE_UPLOAD_FAILED.MESSAGE);
} catch (MyException e) {
e.printStackTrace();
throw new FastDFSException(ErrorCode.FILE_UPLOAD_FAILED.CODE, ErrorCode.FILE_UPLOAD_FAILED.MESSAGE);
} finally {
// 關閉流
if(is != null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 返還對象
TrackerServerPool.returnObject(trackerServer);
return path;
}
/**
* 以附件形式下載下傳檔案
*
* @param filepath 檔案路徑
* @param response
*/
public void downloadFile(String filepath, HttpServletResponse response) throws FastDFSException {
download(filepath, null, null, response);
}
/**
* 下載下傳檔案 輸出檔案
*
* @param filepath 檔案路徑
* @param os 輸出流
*/
public void downloadFile(String filepath, OutputStream os) throws FastDFSException {
download(filepath, null, os, null);
}
/**
* 以附件形式下載下傳檔案 可以指定檔案名稱.
*
* @param filepath 檔案路徑
* @param filename 檔案名稱
* @param response HttpServletResponse
*/
public void downloadFile(String filepath, String filename, HttpServletResponse response) throws FastDFSException {
download(filepath, filename, null, response);
}
/**
* 下載下傳檔案
*
* @param filepath 檔案路徑
* @param filename 檔案名稱
* @param os 輸出流
* @param response HttpServletResponse
*/
public void download(String filepath, String filename, OutputStream os, HttpServletResponse response) throws FastDFSException {
if(StringUtils.isBlank(filepath)){
throw new FastDFSException(ErrorCode.FILE_PATH_ISNULL.CODE, ErrorCode.FILE_PATH_ISNULL.MESSAGE);
}
filepath = toLocal(filepath);
// 檔案名
if (StringUtils.isBlank(filename)) {
filename = getOriginalFilename(filepath);
}
String contentType = EXT_MAPS.get(getFilenameSuffix(filename));
if(logger.isDebugEnabled()){
logger.debug("download file, filepath = {}, filename = {}", filepath, filename);
}
TrackerServer trackerServer = TrackerServerPool.borrowObject();
StorageClient1 storageClient = new StorageClient1(trackerServer, null);
InputStream is = null;
try {
// 下載下傳
byte[] fileByte = storageClient.download_file1(filepath);
if(fileByte == null){
throw new FastDFSException(ErrorCode.FILE_NOT_EXIST.CODE, ErrorCode.FILE_NOT_EXIST.MESSAGE);
}
if (response != null) {
os = response.getOutputStream();
// 設定響應頭
if (StringUtils.isNotBlank(contentType)) {
// 檔案編碼 處理檔案名中的 '+'、' ' 特殊字元
String encoderName = URLEncoder.encode(filename, "UTF-8").replace("+", "%20").replace("%2B", "+");
response.setHeader("Content-Disposition", "attachment;filename=\"" + encoderName + "\"");
response.setContentType(contentType + ";charset=UTF-8");
response.setHeader("Accept-Ranges", "bytes");
}
}
is = new ByteArrayInputStream(fileByte);
byte[] buffer = new byte[1024 * 5];
int len = 0;
while ((len = is.read(buffer)) > 0) {
os.write(buffer, 0, len);
}
os.flush();
} catch (IOException e) {
e.printStackTrace();
} catch (MyException e) {
e.printStackTrace();
throw new FastDFSException(ErrorCode.FILE_DOWNLOAD_FAILED.CODE, ErrorCode.FILE_DOWNLOAD_FAILED.MESSAGE);
} finally {
// 關閉流
try {
if(is != null){
is.close();
}
if(os != null){
os.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
// 返還對象
TrackerServerPool.returnObject(trackerServer);
}
/**
* 下載下傳檔案
*
* @param filepath 檔案路徑
* @return 傳回檔案位元組
* @throws FastDFSException
*/
public byte[] download(String filepath) throws FastDFSException {
logger.info("下載下傳檔案路徑:"+filepath);
if(StringUtils.isBlank(filepath)){
throw new FastDFSException(ErrorCode.FILE_PATH_ISNULL.CODE, ErrorCode.FILE_PATH_ISNULL.MESSAGE);
}
TrackerServer trackerServer = TrackerServerPool.borrowObject();
StorageClient1 storageClient = new StorageClient1(trackerServer, null);
InputStream is = null;
byte[] fileByte = null;
try {
fileByte = storageClient.download_file1(filepath);
if(fileByte == null){
throw new FastDFSException(ErrorCode.FILE_NOT_EXIST.CODE, ErrorCode.FILE_NOT_EXIST.MESSAGE);
}
} catch (IOException e) {
e.printStackTrace();
} catch (MyException e) {
e.printStackTrace();
throw new FastDFSException(ErrorCode.FILE_DOWNLOAD_FAILED.CODE, ErrorCode.FILE_DOWNLOAD_FAILED.MESSAGE);
}
// 返還對象
TrackerServerPool.returnObject(trackerServer);
return fileByte;
}
/**
* 删除檔案
*
* @param filepath 檔案路徑
* @return 删除成功傳回 0, 失敗傳回其它
*/
public int deleteFile(String filepath) throws FastDFSException {
if(StringUtils.isBlank(filepath)){
throw new FastDFSException(ErrorCode.FILE_PATH_ISNULL.CODE, ErrorCode.FILE_PATH_ISNULL.MESSAGE);
}
TrackerServer trackerServer = TrackerServerPool.borrowObject();
StorageClient1 storageClient = new StorageClient1(trackerServer, null);
int success = 0;
try {
success = storageClient.delete_file1(filepath);
if(success != 0){
throw new FastDFSException(ErrorCode.FILE_DELETE_FAILED.CODE, ErrorCode.FILE_DELETE_FAILED.MESSAGE);
}
} catch (IOException e) {
e.printStackTrace();
} catch (MyException e) {
e.printStackTrace();
throw new FastDFSException(ErrorCode.FILE_DELETE_FAILED.CODE, ErrorCode.FILE_DELETE_FAILED.MESSAGE);
}
// 返還對象
TrackerServerPool.returnObject(trackerServer);
return success;
}
/**
* 擷取檔案資訊
*
* @param filepath 檔案路徑
* @return 檔案資訊
*
* <pre>
* {<br>
* "SourceIpAddr": 源IP <br>
* "FileSize": 檔案大小 <br>
* "CreateTime": 建立時間 <br>
* "CRC32": 簽名 <br>
* } <br>
* </pre>
*/
public Map<String, Object> getFileInfo(String filepath) throws FastDFSException {
TrackerServer trackerServer = TrackerServerPool.borrowObject();
StorageClient1 storageClient = new StorageClient1(trackerServer, null);
FileInfo fileInfo = null;
try {
fileInfo = storageClient.get_file_info1(filepath);
} catch (IOException e) {
e.printStackTrace();
} catch (MyException e) {
e.printStackTrace();
}
// 返還對象
TrackerServerPool.returnObject(trackerServer);
Map<String, Object> infoMap = new HashMap<>(4);
infoMap.put("SourceIpAddr", fileInfo.getSourceIpAddr());
infoMap.put("FileSize", fileInfo.getFileSize());
infoMap.put("CreateTime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(fileInfo.getCreateTimestamp()));
infoMap.put("CRC32", fileInfo.getCrc32());
return infoMap;
}
/**
* 擷取檔案描述資訊
*
* @param filepath 檔案路徑
* @return 檔案描述資訊
*/
public Map<String, Object> getFileDescriptions(String filepath) throws FastDFSException {
TrackerServer trackerServer = TrackerServerPool.borrowObject();
StorageClient1 storageClient = new StorageClient1(trackerServer, null);
NameValuePair[] nvps = null;
try {
nvps = storageClient.get_metadata1(filepath);
} catch (IOException e) {
e.printStackTrace();
} catch (MyException e) {
e.printStackTrace();
}
// 返還對象
TrackerServerPool.returnObject(trackerServer);
Map<String, Object> infoMap = null;
if (nvps != null && nvps.length > 0) {
infoMap = new HashMap<>(nvps.length);
for (NameValuePair nvp : nvps) {
infoMap.put(nvp.getName(), nvp.getValue());
}
}
return infoMap;
}
/**
* 擷取源檔案的檔案名稱
*
* @param filepath 檔案路徑
* @return 檔案名稱
*/
public String getOriginalFilename(String filepath) throws FastDFSException {
Map<String, Object> descriptions = getFileDescriptions(filepath);
if (descriptions != null && descriptions.get(FILENAME) != null) {
return (String) descriptions.get(FILENAME);
}
return null;
}
/**
* 擷取檔案名稱的字尾
*
* @param filename 檔案名 或 檔案路徑
* @return 檔案字尾
*/
public static String getFilenameSuffix(String filename) {
String suffix = null;
String originalFilename = filename;
if (StringUtils.isNotBlank(filename)) {
if (filename.contains(SEPARATOR)) {
filename = filename.substring(filename.lastIndexOf(SEPARATOR) + 1);
}
if (filename.contains(POINT)) {
suffix = filename.substring(filename.lastIndexOf(POINT) + 1);
} else {
if (logger.isErrorEnabled()) {
logger.error("filename error without suffix : {}", originalFilename);
}
}
}
return suffix;
}
/**
* 轉換路徑中的 '\' 為 '/' <br>
* 并把檔案字尾轉為小寫
*
* @param path 路徑
* @return
*/
public static String toLocal(String path) {
if (StringUtils.isNotBlank(path)) {
path = path.replaceAll("\\\\", SEPARATOR);
if (path.contains(POINT)) {
String pre = path.substring(0, path.lastIndexOf(POINT) + 1);
String suffix = path.substring(path.lastIndexOf(POINT) + 1).toLowerCase();
path = pre + suffix;
}
}
return path;
}
/**
* 擷取FastDFS檔案的名稱,如:M00/00/00/wKgzgFnkTPyAIAUGAAEoRmXZPp876.jpeg
*
* @param fileId 包含組名和檔案名,如:group1/M00/00/00/wKgzgFnkTPyAIAUGAAEoRmXZPp876.jpeg
* @return FastDFS 傳回的檔案名:M00/00/00/wKgzgFnkTPyAIAUGAAEoRmXZPp876.jpeg
*/
public static String getFilename(String fileId){
String[] results = new String[2];
StorageClient1.split_file_id(fileId, results);
return results[1];
}
/**
* 擷取通路伺服器的token,拼接到位址後面
*
* @param filepath 檔案路徑 group1/M00/00/00/wKgzgFnkTPyAIAUGAAEoRmXZPp876.jpeg
* @param httpSecretKey 秘鑰
* @return 傳回token,如: token=078d370098b03e9020b82c829c205e1f&ts=1508141521
*/
public static String getToken(String filepath, String httpSecretKey){
// unix seconds
int ts = (int) Instant.now().getEpochSecond();
// token
String token = "null";
try {
token = ProtoCommon.getToken(getFilename(filepath), ts, httpSecretKey);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (MyException e) {
e.printStackTrace();
}
StringBuilder sb = new StringBuilder();
sb.append("token=").append(token);
sb.append("&ts=").append(ts);
return sb.toString();
}
/**
* @return the max file size
*/
public int getMaxFileSize() {
return maxFileSize;
}
/**
* Set max file size, default 100M
* @param maxFileSize the max file size
*/
public void setMaxFileSize(int maxFileSize) {
this.maxFileSize = maxFileSize;
}
}
3.2 上傳、下載下傳、删除等相關Api
import com.cdmtc.common.FastDFSClient;
import com.cdmtc.config.ErrorCode;
import com.cdmtc.config.FastDFSException;
import com.cdmtc.config.FileResponseData;
import com.cdmtc.utils.FileCheck;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
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.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 檔案接口
*/
@RestController
@RequestMapping("web/fastdfs/file")
@PropertySource("classpath:config.properties")
@Api(value = "FileObjectController",tags = {"檔案接口"})
public class FileObjectController {
/**
* 檔案伺服器位址
*/
@Value("${file_server_addr}")
private String fileServerAddr;
/**
* http位址
*/
@Value("${fastdfs.httpServerAddr}")
private String httpServerAddr;
/**
* FastDFS秘鑰
*/
@Value("${fastdfs.http_secret_key}")
private String fastDFSHttpSecretKey;
/**
* 上傳檔案通用,隻上傳檔案到伺服器,不會儲存記錄到資料庫
*
* @param file
* @param request
* @return 傳回檔案路徑等資訊
*/
@PostMapping(value = "/upload")
@ApiOperation(value = "上傳檔案通用")
public FileResponseData uploadFileSample(MultipartFile file, HttpServletRequest request){
// System.out.println(httpServerAddr);
return uploadSample(file, request);
}
/**
* 隻能上傳圖檔,隻上傳檔案到伺服器,不會儲存記錄到資料庫. <br>
* 會檢查檔案格式是否正确,預設隻能上傳 ['png', 'gif', 'jpeg', 'jpg'] 幾種類型.
*
* @param file
* @param request
* @return 傳回檔案路徑等資訊
*/
@PostMapping("/upload/image")
@ApiOperation(value = "隻能上傳圖檔")
public FileResponseData uploadImageSample(@RequestParam MultipartFile file, HttpServletRequest request){
// 檢查檔案類型
if(!FileCheck.checkImage(file.getOriginalFilename())){
FileResponseData responseData = new FileResponseData(false);
responseData.setCode(ErrorCode.FILE_TYPE_ERROR_IMAGE.CODE);
responseData.setMessage(ErrorCode.FILE_TYPE_ERROR_IMAGE.MESSAGE);
return responseData;
}
return uploadSample(file, request);
}
/**
* 隻能上傳文檔,隻上傳檔案到伺服器,不會儲存記錄到資料庫. <br>
* 會檢查檔案格式是否正确,預設隻能上傳 ['pdf', 'ppt', 'xls', 'xlsx', 'pptx', 'doc', 'docx'] 幾種類型.
*
* @param file
* @param request
* @return 傳回檔案路徑等資訊
*/
@PostMapping("/upload/doc")
@ApiOperation(value = "隻能上傳文檔")
public FileResponseData uploadDocSample(@RequestParam MultipartFile file, HttpServletRequest request){
// 檢查檔案類型
if(!FileCheck.checkDoc(file.getOriginalFilename())){
FileResponseData responseData = new FileResponseData(false);
responseData.setCode(ErrorCode.FILE_TYPE_ERROR_DOC.CODE);
responseData.setMessage(ErrorCode.FILE_TYPE_ERROR_DOC.MESSAGE);
return responseData;
}
return uploadSample(file, request);
}
/**
* 以附件形式下載下傳檔案
*
* @param filePath 檔案位址
* @param response
*/
@PostMapping("/download")
@ApiOperation(value = "以附件形式下載下傳檔案")
public void downloadFile(String filePath, HttpServletResponse response) throws FastDFSException {
try {
FastDFSClient.getInstance().downloadFile(filePath, response);
} catch (FastDFSException e) {
e.printStackTrace();
throw e;
}
}
/**
* 擷取圖檔 使用輸出流輸出位元組碼,可以使用< img>标簽顯示圖檔<br>
*
* @param filePath 圖檔位址
* @param response
*/
@PostMapping("/download/image")
@ApiOperation(value = "擷取圖檔可以使用< img>标簽顯示圖檔")
public void downloadImage(String filePath, HttpServletResponse response) throws FastDFSException {
try {
FastDFSClient.getInstance().downloadFile(filePath, response.getOutputStream());
} catch (FastDFSException e) {
e.printStackTrace();
throw e;
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 根據指定的路徑删除伺服器檔案,适用于沒有儲存資料庫記錄的檔案
*
* @param filePath
*/
@PostMapping("/delete")
@ApiOperation(value = "據指定的路徑删除伺服器檔案")
public FileResponseData deleteFile(@RequestParam(value = "filePath")String filePath) {
FileResponseData responseData = new FileResponseData();
try {
FastDFSClient.getInstance().deleteFile(filePath);
} catch (FastDFSException e) {
e.printStackTrace();
responseData.setSuccess(false);
responseData.setCode(e.getCode());
responseData.setMessage(e.getMessage());
}
return responseData;
}
/**
* 擷取通路檔案的token
*
* @param filePath 檔案路徑
* @return
*/
@PostMapping("/get/token")
@ApiOperation(value = "擷取通路檔案的token")
public FileResponseData getToken(String filePath){
FileResponseData responseData = new FileResponseData();
// 設定訪檔案的Http位址. 有時效性.
String token = FastDFSClient.getInstance().getToken(filePath, fastDFSHttpSecretKey);
responseData.setToken(token);
responseData.setHttpUrl(httpServerAddr+"/"+filePath+"?"+token);
return responseData;
}
/**
* 上傳通用方法,隻上傳到伺服器,不儲存記錄到資料庫
*
* @param file
* @param request
* @return
*/
public FileResponseData uploadSample(MultipartFile file, HttpServletRequest request){
FileResponseData responseData = new FileResponseData();
try {
// 上傳到伺服器
String filepath = FastDFSClient.getInstance().uploadFileWithMultipart(file);
responseData.setFileName(file.getOriginalFilename());
responseData.setFilePath(filepath);
responseData.setFileType(FastDFSClient.getInstance().getFilenameSuffix(file.getOriginalFilename()));
// 設定訪檔案的Http位址. 有時效性.
String token = FastDFSClient.getInstance().getToken(filepath, fastDFSHttpSecretKey);
responseData.setToken(token);
responseData.setHttpUrl(httpServerAddr+"/"+filepath+"?"+token);
} catch (FastDFSException e) {
responseData.setSuccess(false);
responseData.setCode(e.getCode());
responseData.setMessage(e.getMessage());
}
return responseData;
}
}
若有運作不成功,遇到問題、缺少jar包依賴等可能的問題,請評論告訴我,會第一時間進行解答。