Spring Cloud OpenFeign成功进行文件资源服务间互相传输的一次实例

  • 需求:需要消费者通过服务调用使用生产者的文件上传接口。
  • 实现:这个功能前前后后总共花费了三天的时间了,期间问过很多师兄和朋友,最后总算是出来了一个半成品,因为对于原理还不是很清楚,因此只把成功的实例记录下来。明天进行详细测试,找出问题所在。
  • 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>

  • application.yml
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


  • feignclient
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);

}

  • controller
@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({
            //@ApiImplicitParam(type = "query",name = "createBy",dataType = "String",required = true)
    })
    //@PreAuthorize("hasAuthority('ROLE_USER')")
    @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();
            //文件存储名:UUID+文件类型后缀
            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 apkName = "1";
            //应用包
            String pkName = (String) apkInfo.get("pkName");
            //版本名
            String vName = (String)apkInfo.get("vName");
            //版本号
            long vCode = (Long) apkInfo.get("vCode");
            //注释掉的是阿里云OSS
            url = OSSUtils.upload(folder, UUID.randomUUID().toString()+".apk");
            System.out.println(url);
            folder.delete();
            //设置SysApk
            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("上传失败");
    }
发布了96 篇原创文章 · 获赞 45 · 访问量 7297

猜你喜欢

转载自blog.csdn.net/weixin_43404791/article/details/105082326