- 需求:需要消费者通过服务调用使用生产者的文件上传接口。
- 实现:这个功能前前后后总共花费了三天的时间了,期间问过很多师兄和朋友,最后总算是出来了一个半成品,因为对于原理还不是很清楚,因此只把成功的实例记录下来。明天进行详细测试,找出问题所在。
- pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.hcnet2006.blog</groupId>
<artifactId>blog-base</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>cn.hcnet2006.blog</groupId>
<artifactId>micro-consumer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>micro-consumer</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-boot-admin.version>2.2.2</spring-boot-admin.version>
<docker.image.prefix>47.97.170.173:5000</docker.image.prefix>
</properties>
<dependencies>
<!-- 使用Apache HttpClient替换Feign原生httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<!--feign upload file-->
<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>1.3.3</version>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>${spring-boot-admin.version}</version>
</dependency>
<!--Swagger2文档-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<!--添加消息总线依赖-->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!--使用Maven和Dockerfile命令构建镜像-->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>1.3.6</version>
<configuration>
<!--生成镜像名称-->
<repository>
${docker.image.prefix}/${project.name}
</repository>
<!--生成镜像版本-->
<tag>${project.version}</tag>
<!--推送到私有仓库或者DockerHub时需要开启用户认证-->
<useMavenSettingsForAuth>true</useMavenSettingsForAuth>
<buildArgs>
<JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
<JAR_EXPOSE>8204</JAR_EXPOSE>
</buildArgs>
</configuration>
<!--直接使用 mvn install 命令打包项目, 就会自动构建并推送镜像-->
<executions>
<execution>
<id>default</id>
<phase>install</phase>
<goals>
<goal>build</goal>
<goal>push</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
server:
port: 8213
spring:
application:
name: micro-consumer-1
cloud:
consul:
host: 172.17.0.1
port: 8500
discovery:
service-name: ${spring.application.name}
hostname: 172.17.0.1
health-check-url: http://172.17.0.1:8209/actuator/health
servlet:
multipart:
enabled: true
file-size-threshold: 0
max-file-size: 1000MB
max-request-size: 1000MB
resolve-lazily: false
#解决Feign请求超时问题
#hystrix的超时时间
feign:
client:
config:
default:
connectTimeout: 500000
readTimeout: 500000
loggerLevel: basic
package cn.hcnet2006.blog.microconsumer1.service;
import cn.hcnet2006.blog.microconsumer1.http.HttpResult;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;
@Service
@FeignClient(value = "hcnet-website-1")
@RequestMapping(value = "/upload")
public interface SysApkService {
@RequestMapping(value = "/apk",method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE,
consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public HttpResult upload(@RequestBody MultipartFile uploadFile);
}
@RestController
@RequestMapping("/feign/upload")
public class UploadController {
@Autowired
private SysApkService sysApkService;
@PostMapping(value = "/apk")
public HttpResult upload(MultipartFile uploadFile) {
System.out.println("123");
System.out.println(uploadFile.getOriginalFilename());
return sysApkService.upload(uploadFile);
}
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry){
registry.addMapping("/**")
.allowedOrigins("*") // 允许跨域访问的源
.allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE") // 允许请求方法
.maxAge(168000) // 预检间隔时间
.allowedHeaders("*") // 允许头部设置
.allowCredentials(true); // 是否发送cookie
}
}
@ApiOperation(value = "文件上传",notes = "文件上传")
@ApiImplicitParams({
})
@RequestMapping(value = "/apk",method = RequestMethod.POST)
@CrossOrigin(origins = "*", allowCredentials = "true",allowedHeaders = "*",
methods = {RequestMethod.GET, RequestMethod.DELETE, RequestMethod.HEAD, RequestMethod.OPTIONS, RequestMethod.PUT, RequestMethod.POST, RequestMethod.PATCH})
public HttpResult upload(@RequestBody MultipartFile uploadFile) throws NullPointerException, FileNotFoundException {
try{
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String apkSize = uploadFile.getSize()+"";
String url = ResourceUtils.getURL("").getPath()+uploadFile.getOriginalFilename();
File folder = new File(url);
String apkOldName = uploadFile.getOriginalFilename();
String apkStoName = UUID.randomUUID().toString()+
apkOldName.substring(apkOldName.lastIndexOf("."),apkOldName.length());
uploadFile.transferTo(folder);
Map<String,Object> apkInfo = ApkInfoUtil.readAPK(folder);
String apkName = (String) apkInfo.get("name");
String pkName = (String) apkInfo.get("pkName");
String vName = (String)apkInfo.get("vName");
long vCode = (Long) apkInfo.get("vCode");
url = OSSUtils.upload(folder, UUID.randomUUID().toString()+".apk");
System.out.println(url);
folder.delete();
SysApk sysApk = new SysApk();
sysApk.setApkName(apkName);
sysApk.setApkPk(pkName);
sysApk.setApkVc(vCode);
sysApk.setApkVn(vName);
sysApk.setCreateBy(authentication.getName());
sysApk.setCreateTime(new Date());
sysApk.setLastUpdateBy(authentication.getName());
sysApk.setLastUpdateTime(new Date());
sysApk.setApkSize(apkSize);
sysApk.setApkUrl(url);
sysApk.setDelFlag((byte)0);
sysApkService.save(sysApk);
return HttpResult.ok(sysApk);
}catch (IOException e){
e.printStackTrace();
}
return HttpResult.error("上传失败");
}