最近用springcloud上传文件,消费者端与服务提供端通过feign调用,中间稍微踩了点坑,现将最终可执行代码发布出来:
事先说明,这里 base64编码保存图片文件是个性需求,这些相关代码,各位可以忽略,只关注上传文件的相关代码便可。
如果改成页面传入base64编码或消费者端传入base64编码,则在feign与底层service接口直接用String 参数传递接收便可。
<!-- Feigh uploadFile-->
<dependency>
<groupId>io.github.openfeign.form</groupId>
<artifactId>feign-form</artifactId>
<version>3.5.0</version>
</dependency>
<dependency>
<groupId>io.github.openfeign.form</groupId>
<artifactId>feign-form-spring</artifactId>
<version>3.5.0</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>RELEASE</version>
</dependency>
版本依赖:springboot版本2.1.3.RELEASE版本,springcloud为GreenWich的最新版本
2.服务提供方各层代码实现类,这是转换成base64字节码保存到数据库的示例。
有些代码不是太完整
@Slf4j
@Service
@RestController
@Transactional(rollbackFor = Exception.class)
@Api(position = 22, tags = {"ApplicationService"}, description = "应用管理服务, 提供增删改查等操作的管理接口")
public class ApplicationServiceImpl implements ApplicationService {
@Autowired
private ApplicationDao applicationDao;
@Override
public String saveLogoById(@NonNull String id, @NonNull MultipartFile logo) {
if (StringUtils.isBlank(id)) {
throw new IllegalArgumentException("appId must be not empty.");
}
byte[] prefix="data:image/png;base64,".getBytes();
byte[] _logo = new byte[0];
try {
_logo= Base64.encodeBase64(logo.getBytes());
} catch (Exception e) {
throw new RuntimeException(e);
}
byte[] mylogo=new byte[prefix.length+_logo.length];
System.arraycopy(prefix, 0, mylogo, 0, prefix.length);
System.arraycopy(_logo, 0, mylogo, prefix.length, _logo.length);
applicationDao.logoSaveById(id, mylogo);
return id;
}
@Override
public ResponseEntity<byte[]> getLogoById(@NonNull String id) {
byte[] logo = ((ApplicationDao) this._getBaseDao()).logoGetById(id);
return new ResponseEntity<>(logo, HttpStatus.OK);
}
}
dao中之保存获取并无不同。
xml之写法
<update id="logoSave" parameterType="hashmap"> UPDATE ECS_APP SET APP_LOGO=#{logo},APP_UPDATED_AT = CURRENT_TIMESTAMP(3) WHERE APP_ID = #{id} </update>
3.若直接以base64编码后做为字符串传入,也是一样。
4.feign客户端接口:
@FeignClient(value = "ecs", contextId = "ApplicationService" ,configuration = FeignMultipartSupportConfig.class)
@RequestMapping(value = "/ApplicationService")
public interface ApplicationService {
@PostMapping(value = "/saveLogoById",produces = {MediaType.APPLICATION_JSON_VALUE}, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@ApiOperation(position = 62, value = "保存指定ID应用的商标", notes = "如果保存不成功, 抛出异常")
@ApiImplicitParams(value = {
@ApiImplicitParam(paramType = "query", name = "id", required = true, dataType = "string", value = "应用ID"),
//这里没logo的
})
String saveLogoById(@ApiIgnore @NonNull @RequestParam(value = "id") String id, @ApiIgnore @NonNull @RequestPart(value = "logo") MultipartFile logo);
@PostMapping(value = "/getLogoById", produces = {MediaType.APPLICATION_JSON_VALUE})
@ApiOperation(position = 61, value = "获取指定ID应用的商标", produces = MediaType.APPLICATION_JSON_VALUE, notes = "如果获取成功, 返回商标, 无商标返回null, 如果应用不存在或其它原因, 则抛出异常")
@ApiImplicitParams(value = {
@ApiImplicitParam(paramType = "query", name = "id", required = true, dataType = "string", value = "应用ID"),
})
ResponseEntity<byte[]> getLogoById(@ApiIgnore @NonNull @RequestParam(value = "id") String id);
}
@FeignClient(value = "ecs", contextId = "ApplicationService" ,configuration = FeignMultipartSupportConfig.class) 这里的FeignMultipartSupportConfig类示例代码
import feign.codec.Encoder; import feign.form.spring.SpringFormEncoder; import org.springframework.beans.factory.ObjectFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.http.HttpMessageConverters; import org.springframework.cloud.openfeign.support.SpringEncoder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class FeignMultipartSupportConfig { @Autowired private ObjectFactory<HttpMessageConverters> messageConverters; @Bean public Encoder feignFormEncoder() { return new SpringFormEncoder(new SpringEncoder(messageConverters)); } @Bean public feign.Logger.Level multipartLoggerLevel() { return feign.Logger.Level.FULL; } }
5.消费者端测试代码:
@PostMapping(value = "/testLogo")
@ApiOperation(position = 62, value = "测试Logo",response = Map.class, notes = "如果保存不成功, 抛出异常")
public boolean testLogo(){
File file = new File("E:\\haha.png");
DiskFileItem fileItem = (DiskFileItem) new DiskFileItemFactory().createItem("logo",
MediaType.TEXT_PLAIN_VALUE, true, file.getName());
try (InputStream input = new FileInputStream(file);
OutputStream os = fileItem.getOutputStream()) {
IOUtils.copy(input, os);
} catch (Exception e) {
throw new IllegalArgumentException("Invalid file: " + e, e);
}
MultipartFile logo = new CommonsMultipartFile(fileItem);
log.info(applicationService.saveLogoById("20190520132707572-1007-CD574C23C",logo));
return true;
}
注意这里有个坑,createItem("logo",这里的名称一定要各feign里的参数名称 一样,否则调用时 feign无法传入此参数。消费者端logo参数无值。
6.消费者端正式代码:
@Slf4j @RestController @RequestMapping("/app") @Api(tags = {"ApplicationController"}, description = "应用管理服务")
@PostMapping(value = "/saveLogo") @ApiOperation(position = 62, value = "保存指定ID应用的商标", response = Map.class, notes = "如果保存不成功, 抛出异常") @ApiImplicitParams(value = { @ApiImplicitParam(paramType = "query", name = "appId", required = false, dataType = "string", value = "应用ID"), }) public String saveLogo(@RequestPart(value = "logo") MultipartFile logo, String appId) { if (StringUtils.isBlank(appId)) { Application application = new Application(); application.setName("onlysavelogo_"+RandomStringUtils.random(30)); application.setEntId(AccessIdentity.getEnterpriseId()); appId = applicationService.create(application); } return applicationService.saveLogoById(appId, logo); } @PostMapping(value = "/getLogoById") @ApiOperation(position = 61, value = "获取指定ID应用的商标", produces = MediaType.APPLICATION_JSON_VALUE, notes = "如果获取成功, 返回商标, 无商标返回null, 如果应用不存在或其它原因, 则抛出异常") @ApiImplicitParams(value = { @ApiImplicitParam(paramType = "query", name = "appId", required = true, dataType = "string", value = "应用ID") }) public ResponseEntity<byte[]> getLogoById(@NonNull String appId) { return applicationService.getLogoById(appId); }
}
同时传入图片与对象调用
@PostMapping(value = "/addApplicationInfo") @ApiOperation(position = 62, value = "保存应用完整信息(应用及图片)", response = Map.class, notes = "如果保存不成功, 抛出异常") @ApiImplicitParams(value = { // @ApiImplicitParam(paramType = "query", name = "appId", required = false, dataType = "string", value = "应用ID") }) public String addApplicationInfo(@RequestPart(value = "logo") MultipartFile logo,@NonNull ApplicationVo applicationVo) { //同时上传logo用这个代码 }
这里如此接收参数便可。
经测试是没有问题.
相关推荐
本篇文章主要介绍了使用Spring Cloud Feign上传文件的示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
主要为大家详细介绍了SpringCloud使用Feign文件上传、下载功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
主要介绍了Spring Cloud Feign的文件上传实现的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
主要为大家详细介绍了Spring Cloud中FeignClient实现文件上传功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
业务层:Spring IOC、Aop事务控制、Spring Task任务调度、Feign、Ribbon、Spring AMQP、Spring Data Redis等。 控制层:Spring MVC、FastJSON、RestTemplate、Spring Security Oauth2+JWT等 微服务治理:Eureka、...
├36 6.8通过Zuul上传文件,禁用Zuul的Filters.avi ├37 6.9 Zuul的回退.avi ├38 6.10 使用Sidecar支持异构平台的微服务.avi ├39 6.10 Sidecar补充.avi ├4 服务提供者与服务消费者.avi ├4 服务提供者与服务消费...
基于Vue+SpringCloud博客的设计与实现---微服务基础版本组件1.0版本 博客采用Vue+SpringCloud前后分离的方式。博客采用了高可用Eureka(可以替换成其他微服务组件)以及高可用Zuul,使用以Es搜索引擎作为Zpkin的存储...
项目简介:在线考试系统,采用vue与springcloud...springCloud(eureka、zuul、feign)搭建微服务工程 nginx反向代理域名 采用jwt+rsa加密生成token,写入cookie的方式做无状态登录 maven、idea、postman工具开发
springcloud restful服务者、消费者 eureka ribbon和feign hystrix 路由网关 config 文件上传
在Spring Cloud 的Feign组件中并不支持文件的传输,会出现错误。通过Feign 扩展 可以实现Feign 单个文件和多个文件的上传,示例代码中演示了单个文件上传,多个文件上参考博客自己实现即可。文章地址:...
eureka用户服务注册,config用于服务注册,config-client作为客户端注册,通过ribbon实现了客户端访问study-springcloud-service-1,study-springcloud-service-2间负载均衡 等,由于上传文件大小限制 另一部分请参考...
毕业设计,基于SpringBoot+SpringCloud+LightMQ+Vue开发的前后端分离的智能招聘系统,技术栈丰富 使用说明 使用时麻烦将Nacos,ZipKin,Sentinel等组件自行搭建使用,本人服务器性能较差 存储在Nacos中的配置文件在...
毕业设计之SpringCloud-B2C电子商务平台服务端。 开发技术 Spring,SpringMVC,Spring Cloud相关组件 Mybatis,Maven Mysql,Redis Jquery,Ajax... 利用SpringBoot的文件上传完成用户头像上传,Ajax实现商品多图片上传
基于Vue+SpringCloud博客的设计与实现---微服务基础版本组件1.0版本 ...用户文件头像上传中心:博客所用到的所有的图片和用户的图片均用阿里云OSS文件服务器,外网url,也可以采用本地机器存储。 用户签到中心
+ springBoot + springCloud + 日志组件logback-spring + 多配置 + 多数据源 + swagger2 + 异步线程池配置 + mybatis-plus + 令牌token + 全局异常管理 + 统一返回数据拦截 + 自定义异常 + 处理ajax跨域请求 + ...
配置阿里云OSS和邮箱密钥(或修改文件上传方式) 将通用模块打包,并在其他模块中正确引用 项目启动顺序:网关服务->其他服务->搜索服务 前端资源链接:https://download.csdn.net/download/qq_36584673/88534030
使用Spring Cloud开发部署。项目采用微服务开发,采用JWT技术作为身份验证手段,前进行分离。目前前交互使用JSON方式, 和通信方式正在开发中。技术栈:前端:Vue.JS初步:春天的云数据库:MongoDB中间件:RabbitMQ...
在线考试系统,采用vue与springcloud微服务架构开发,前后端...- springCloud(eureka、zuul、feign)搭建微服务工程 - nginx反向代理域名 - 采用jwt+rsa加密生成token,写入cookie的方式做无状态登录 - maven、idea、
spring-cloud2 名称 端口 作用 eureka-server 8081 服务注册中心 eureka-client 8082 服务提供者 consul 8083/8084 服务提供者/服务发现 eureka-consumer 8085 服务消费者 feign 8086 声明式服务消费者 feign-upload...