一、背景
我们已经把文件服务器+微服务项目跑起来了。也能看到他的java进程了
那就结束了吗?大错特错,这只是准备好了文件服务器,还有应用端调用方。本篇文章,将详细介绍应用方,通过spring cloud alibaba + feign服务调用 + sentinal熔断限流 来处理微服务接口实现文件上传下载的功能。
二、前提准备
文件服务器项目:参考上篇文章
(7条消息) springboot文件服务器 一(IO流+微服务包含swagger、出入参统一格式、log4j2日志)_无敌小田田的博客-CSDN博客https://blog.csdn.net/qq_36602951/article/details/120726620三、代码
构造:gradle + spring boot 的项目
1、依赖文件 参考上篇build.gradle 新增加如下内容
ext {
set('springCloudVersion', "2020.0.2")
set('vaadinVersion', "14.4.5")
set('comAlibabaCloud',"2021.1")
}
dependencies {
implementation group: 'com.alibaba.boot', name: 'nacos-config-spring-boot-starter',
version: '0.2.1'
implementation('com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery')
implementation ('org.springframework.cloud:spring-cloud-starter-openfeign')
implementation ('org.springframework.cloud:spring-cloud-loadbalancer')
implementation ('com.alibaba.cloud:spring-cloud-starter-alibaba-sentinel')
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
mavenBom "com.alibaba.cloud:spring-cloud-alibaba-dependencies:${comAlibabaCloud}"
}
}
2、application.properties配置文件
#微服务配置开始 spring.application.name=onecrm-app spring.cloud.nacos.discovery.server-addr=1.2.3.4:8848 spring.cloud.nacos.discovery.namespace=*********************** management.endpoints.web.exposure.include=* #feign配置 #开启饥饿加载,默认是false懒加载,懒加载第一次访问会很慢 ribbon.eager-load.enabled=true #为哪些客户端开启饥饿加载,多个客户端使用逗号分隔(非必须) ribbon.eager-load.clients=file-fileManager #读取超时时间 feign.client.config.default.read-timeout=60000 #连接超时时间 feign.client.config.default.connect-timeout=60000 #某个服务超时时间 feign.client.config.service-provide.read-timeout=1000 #配置feign默认使用httpclient 远程调用 feign.httpclient.enabled=true #连接池 feign.httpclient.max-connections=200 #每个节点最大连接池 feign.httpclient.max-connections-per-route=50 feign.sentinel.enabled=true #微服务配置完毕
3、Main函数 WebappApplication.java文件
@EnableDiscoveryClient //开启服务注册与发现功能
@EnableFeignClients //开启Feign
public class WebappApplication {
public static void main(String[] args) {
SpringApplication.run(WebappApplication.class, args);
}
}
4、Feign调用远程服务接口
在路径com.xxxx.we.feign 目录下设置四个文件
① FeignConfiguration 配置类
package com.****.webapp.feign;
import org.springframework.context.annotation.Bean;
public class FeignConfiguration {
@Bean
public FeignFileManageFallback echoServiceFallback(){
return new FeignFileManageFallback();
}
}
② FeignFileManage 接口 远程调用文件服务器的接口
package com.****.app.feign;
import com.****.app.common.model.ApibaseMessage;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;
@FeignClient(name="file-fileManager",
fallback = FeignFileManageFallback.class,
configuration = FeignConfiguration.class)
public interface FeignFileManage {
@RequestMapping(value="/test/mobile", method = {RequestMethod.POST})
String test();
//单文件上传
@RequestMapping(value = "/file/upload", method = {RequestMethod.POST}, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
ApibaseMessage fileUpload(@RequestPart("file") MultipartFile file, @RequestParam("type") String type) ;
//多文件上传
@RequestMapping(value = "/file/MultiUpload",method = {RequestMethod.POST}, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
ApibaseMessage multiFileUpload(@RequestPart("files") MultipartFile[] files, @RequestParam("type") String type);
//文件下载
@RequestMapping(value = "/file/download", method = {RequestMethod.GET})
ResponseEntity download(@RequestParam("filePath") String filePath) throws Exception;
//文件删除
@RequestMapping(value = "/file/delete",method = {RequestMethod.DELETE})
ApibaseMessage deleteFile(@RequestParam("filePath") String filePath) ;
}
③FeignFileManageback 接口报错统一处理(接口熔断)
package com.****.app.feign;
import com.****.app.common.model.ApibaseMessage;
import com.****.app.common.model.JsonResult;
import com.****.app.enums.CheckExceptionEnum;
import org.springframework.http.ResponseEntity;
import org.springframework.web.multipart.MultipartFile;
public class FeignFileManageFallback implements FeignFileManage{
@Override
public String test() {
return "test222";
}
@Override
public ApibaseMessage fileUpload(MultipartFile file, String type) {
return ApibaseMessage.getOperationSucceedInstance(JsonResult.jsonErrorMsg(Integer.valueOf(CheckExceptionEnum.MICRO_FILE_MGR_UP.getCode()), CheckExceptionEnum.MICRO_FILE_MGR_UP.getMsg()));
}
@Override
public ApibaseMessage multiFileUpload(MultipartFile[] files, String type) {
return ApibaseMessage.getOperationSucceedInstance(JsonResult.jsonErrorMsg(Integer.valueOf(CheckExceptionEnum.MICRO_FILE_MGR_UP.getCode()), CheckExceptionEnum.MICRO_FILE_MGR_UP.getMsg()));
}
@Override
public ResponseEntity download(String filePath) {
ResponseEntity result= ResponseEntity.noContent().build();
return result;
}
@Override
public ApibaseMessage deleteFile(String filePath) {
return ApibaseMessage.getOperationSucceedInstance(JsonResult.jsonErrorMsg(Integer.valueOf(CheckExceptionEnum.MICRO_FILE_MGR_DEL.getCode()), CheckExceptionEnum.MICRO_FILE_MGR_DEL.getMsg()));
}
}
④ MyRibbonConfig 负载均衡规则
package com.****.webapp.feign;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class MyRibbonConfig {
@LoadBalanced //负载均衡
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
5、Controller端调用接口 给前端即可
package com.****.app.controller;
import com.****.app.annotation.NeedLog;
import com.****.app.common.model.ApibaseMessage;
import com.****.webapp.feign.FeignFileManage;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import springfox.documentation.annotations.ApiIgnore;
@ApiIgnore
@Controller
@RequestMapping("/file")
public class FileUploadController {
public static final Logger logger = LoggerFactory.getLogger(FileUploadController.class);
@Value("${file.save.path}")
private String defaultPath;
@Autowired
private FeignFileManage feignFileManage;
@ApiOperation(value = "上传文件 - 单个")
@NeedLog(value = "上传文件 - 单个")
@ApiImplicitParams({
@ApiImplicitParam(paramType = "query", name = "type", value = "文件分类", dataType = "String")
})
@RequestMapping(value = "upload", method = {RequestMethod.POST})
@ResponseBody
public ApibaseMessage fileUpload(@RequestParam("file") MultipartFile file, @RequestParam("type") String type)throws Exception{
try {
return feignFileManage.fileUpload(file, type);
} catch (Exception e) {
throw e;
}
}
@ApiOperation(value = "上传文件 - 多个")
@NeedLog(value = "上传文件 - 多个")
@ApiImplicitParams({
@ApiImplicitParam(paramType = "query", name = "type", value = "文件分类", dataType = "String")
})
@RequestMapping(value = "MultiUpload",method = {RequestMethod.POST})
@ResponseBody
public ApibaseMessage multiFileUpload(@RequestParam("files") MultipartFile[] files,@RequestParam("type") String type) throws Exception{
try {
return feignFileManage.multiFileUpload(files,type);
} catch (Exception e) {
throw e;
}
}
@ApiOperation(value = "下载文件")
@NeedLog(value = "下载文件")
@ApiImplicitParams({
@ApiImplicitParam(paramType = "query", name = "filePath", value = "文件路径", dataType = "String")
})
@RequestMapping(value = "download", method = {RequestMethod.GET})
@ResponseBody
public ResponseEntity download(@RequestParam String filePath) throws Exception {
return feignFileManage.download(filePath);
}
@ApiOperation(value = "删除文件")
@NeedLog(value = "删除文件")
@ApiImplicitParams({
@ApiImplicitParam(paramType = "query", name = "filePath", value = "文件路径", dataType = "String")
})
@RequestMapping(value = "delete",method = {RequestMethod.DELETE})
@ResponseBody
public ApibaseMessage deleteFile(@RequestParam String filePath) throws Exception{
try {
return feignFileManage.deleteFile(filePath);
} catch (Exception e) {
throw e;
}
}
}
综上所述,即完成了一整套的 文件服务器开发 + 以及应用端封装IO流接口的一整套方法。



