引入openfeign
記住必須引入openfeign依賴,而不是feign依賴,引入openfeign就不用了feign了,openfeign包含了feign的所有功能
<springcloud.openfeign.version>2.1.1.RELEASE</springcloud.openfeign.version>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>${springcloud.openfeign.version}</version>
</dependency>
文件上傳微服務:
必須指定爲表單數據類型,文件接收加入@RequestPart註解指定文件名,這個名字是MultipartFile 的getName方法可以拿到的,也就是前端傳輸構造的表單提交對應的file的name值,或者是自己用js構造表單數據自己指定的名字,記住如果@RequestPart註解指定的值和getName() 方法拿到的值不對應,是接收不到的
@RestController
@RequestMapping("/file")
public class UploadController {
@Autowired
private FastDfsService fastDfsService;
/**
* 單文件上傳
* @param file
* @return
*/
@PostMapping(value = "/upload",consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public JsonResult uploadFile(@RequestPart("file") MultipartFile file) {
System.out.print("文件上傳服務中:"+file.getOriginalFilename());
Map<String, String> map = null;
try {
map = fastDfsService.uploadFile(file);
} catch (IOException e) {
new JsonResult<>(e);
}
return new JsonResult(map, "文件上傳成功");
}
/**
* 多文件上傳
* @param
* @return
*/
@PostMapping(value = "/uploadFiles",consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public JsonResult uploadFiles(@RequestPart("files") MultipartFile[] files) {
List<Object> data = new ArrayList<>();
for (MultipartFile file:files){
Map<String, String> map = null;
try {
map = fastDfsService.uploadFile(file);
data.add(map);
} catch (IOException e) {
new JsonResult<>(e);
}
}
return new JsonResult(data, "文件上傳成功");
}
@PostMapping(value = "/deleteFile")
public Map<String,Object> deleteFile(@RequestParam("fileUrl") String fileUrl){
int t = fastDfsService.deleteFile(fileUrl);
Map<String,Object> message = new HashMap<>();
if(t==1){
message.put("code",1);
message.put("msg","刪除文件成功");
return message;
}
message.put("code",0);
message.put("msg","刪除文件失敗");
return message;
}
}
調用服務:
@FeignClient(value = "file-upload", configuration = UpLoadFeignClient.MultipartSupportConfig.class)
public interface UpLoadFeignClient {
@PostMapping(value = "/file/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public JsonResult uploadFile(@RequestPart("file") MultipartFile file);
@PostMapping(value = "/file/uploadFiles",consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public JsonResult uploadFiles(@RequestPart("files") MultipartFile[] files);
@PostMapping(value = "/file/deleteFile")
public Map<String,Object> deleteFile(@RequestParam("fileUrl") String fileUrl);
@Configuration
class MultipartSupportConfig {
@Bean
public Encoder feignFormEncoder() {
return new SpringFormEncoder();
}
}
}
UploadFileServiceImpl.java
@Service
public class UploadFileServiceImpl implements UploadFileService {
@Autowired
private UpLoadFeignClient upLoadFeignClient;
@Override
public JsonResult uploadFile(MultipartFile file) {
return upLoadFeignClient.uploadFile(file);
}
@Override
public JsonResult uploadFiles(MultipartFile[] files) {
return upLoadFeignClient.uploadFiles(files);
}
@Override
public Map<String, Object> deleteFile(String fileUrl) {
return upLoadFeignClient.deleteFile(fileUrl);
}
}
配置fdfs文件服務器:
<fastDFS.client.version>1.26.1-RELEASE</fastDFS.client.version>
<!--FastDFS客戶端-->
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
<version>${fastDFS.client.version}</version>
</dependency>
application.yml或application.properties
server:
port: 8082
spring:
application:
name: file-upload
servlet:
multipart:
max-file-size: 10MB #限制文件大小
eureka:
client:
service-url:
defaultZone: http://xx:[email protected]:10086/eureka
instance:
ip-address: 127.0.0.1
prefer-ip-address: true
fdfs:
soTimeout: 1500 #socket連接超時時長
connectTimeout: 600 #連接tracker服務器超時時長
resHost: 61.157.96.xx
storagePort: 22100
thumbImage: #縮略圖生成參數,可選
width: 150
height: 150
trackerList: #TrackerList參數,支持多個,我這裏只有一個,如果有多個在下方加- x.x.x.x:port
- 61.157.96.xx:22122
FastDFSConfig.java
@Component
@Data
public class FastDFSConfig {
@Value("${fdfs.resHost}")
private String resHost;
@Value("${fdfs.storagePort}")
private String storagePort;
}
FastDFSClientImporter.java
@Configuration
@Import(FdfsClientConfig.class)//// 解決jmx重複註冊bean的問題
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
public class FastDFSClientImporter {
@Bean
public MultipartConfigElement multipartConfigElement(){
MultipartConfigFactory factory = new MultipartConfigFactory();
// 一個文件最大KB,MB
factory.setMaxFileSize(DataSize.ofMegabytes(10));
// 設置總上傳數據總大小
factory.setMaxRequestSize(DataSize.ofMegabytes(20));
// 設置文件大小限制 ,超出設置頁面會拋出異常信息,
// 這樣在文件上傳的地方就需要進行異常信息的處理了;
//factory.setMaxFileSize("128MB"); // KB,MB
/// 設置總上傳數據總大小
//factory.setMaxRequestSize("256MB");
//設置文件路徑
//factory.setLocation("/excel_src");
return factory.createMultipartConfig();
}
}
FastDfsService.java
import com.github.tobato.fastdfs.domain.StorePath;
import com.github.tobato.fastdfs.domain.ThumbImageConfig;
import com.github.tobato.fastdfs.exception.FdfsUnsupportStorePathException;
import com.github.tobato.fastdfs.proto.storage.DownloadByteArray;
import com.github.tobato.fastdfs.proto.storage.DownloadFileWriter;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.xx.upload.config.FastDFSConfig;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
/**
* @data ${DATA}
*/@Slf4j
@Component
public class FastDfsService {
@Autowired
private FastFileStorageClient storageClient;
@Autowired
private FastDFSConfig fastDFSConfig; // 項目參數配置
@Autowired
private ThumbImageConfig thumbImageConfig;
/**
* 上傳一個文件
*/
public Map<String, String> uploadFile(MultipartFile file) throws IOException {
StorePath storePath = storageClient.uploadFile(file.getInputStream(), file.getSize(), FilenameUtils.getExtension(file.getOriginalFilename()), null);
return getResult(storePath);
}
/**
* 將一段字符串生成一個文件上傳
*/
public Map<String, String> uploadFile(String content, String fileExtension) {
byte[] buff = content.getBytes(Charset.forName("UTF-8"));
ByteArrayInputStream stream = new ByteArrayInputStream(buff);
StorePath storePath = storageClient.uploadFile(stream, buff.length, fileExtension, null);
return getResult(storePath);
}
/**
* 上傳一張圖片, 服務器生成2張圖片, 一張原圖, 一張縮略圖
*/
public Map<String, String> uploadImg(MultipartFile file) throws IOException {
StorePath storePath = storageClient.uploadImageAndCrtThumbImage(
file.getInputStream(), file.getSize(), FilenameUtils.getExtension(file.getOriginalFilename()), null);
String smallImgPath = thumbImageConfig.getThumbImagePath(storePath.getPath());
Map<String, String> resultMap = getResult(storePath);
resultMap.put("smallImgPath", smallImgPath);
return resultMap;
}
// 封裝上傳的 返回結果
private Map<String, String> getResult(StorePath storePath) {
Map<String, String> resultMap = new HashMap<String, String>();
String fileUrl = "http://" + fastDFSConfig.getResHost() + ":" + fastDFSConfig.getStoragePort() + "/" + storePath.getFullPath();
resultMap.put("fileUrl", fileUrl);
resultMap.put("fullPath", storePath.getFullPath());
resultMap.put("path", storePath.getPath());
resultMap.put("group", storePath.getGroup());
return resultMap;
}
/**
* 下載文件
*/
public String downloadFile(String group, String path, String filePath) {
String downloadFile = storageClient.downloadFile(group, path, new DownloadFileWriter(filePath));
return downloadFile;
}
/**
* 下載文件
*/
public byte[] downloadFile(String group, String path) {
byte[] bytes = storageClient.downloadFile(group, path, new DownloadByteArray());
return bytes;
}
/**
* 刪除文件
*/
public int deleteFile(String fileUrl) {
if (StringUtils.isEmpty(fileUrl)) {
return 0;
}
try {
StorePath storePath = StorePath.praseFromUrl(fileUrl);
storageClient.deleteFile(storePath.getGroup(), storePath.getPath());
} catch (FdfsUnsupportStorePathException e) {
log.warn(e.getMessage());
return 0;
}
return 1;
}
/**
* 刪除文件
*/
public int deleteFile(String group, String path) {
if (StringUtils.isEmpty(group) || StringUtils.isEmpty(path)) {
return 0;
}
try {
storageClient.deleteFile(group, path);
} catch (Exception e) {
log.warn(e.getMessage());
return 0;
}
return 1;
}
}