使用Spring cloud+zuul使用API网关进行上传文件
项目结构如下:
ZuulUploadController类
package com.example.demo.controller;
import java.io.File;
import java.io.IOException;
import org.springframework.stereotype.Controller;
import org.springframework.util.FileCopyUtils;
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;
@Controller
public class ZuulUploadController {
/**
* 上传文件。
*
* @param file
* @return
* @throws IOException
*/
@RequestMapping(value = "/upload", method = RequestMethod.POST)
@ResponseBody
public String uploadFile(@RequestParam(value = "file", required = true)MultipartFile file) throws IOException{
byte[] bytes = file.getBytes();
File fileToSave = new File(file.getOriginalFilename());
FileCopyUtils.copy(bytes, fileToSave);
return fileToSave.getAbsolutePath();
}
}
EurekaApplication类
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
//简单文件上传微服务采取curl或者页面点击实现文件上传。
@EnableEurekaClient
@SpringBootApplication //开启启动程序入口类
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}
}
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- 注意:1、由于在spring-cloud-zuul-api-gateway-upload配置了path为upload,故在访问这里的上传的action前面需要加上path前缀路径;2、由于上传的文件名含有中文名,故在上传路径前面加上zuul即可解决乱码 -->
<form method="POST" enctype="multipart/form-data" action="/zuul/upload/upload">
File to upload:
<input type="file" name="file">
<input type="submit" value="Upload">
</form>
</body>
</html>
application.yml配置
server:
port: 8043
spring:
application:
name: spring-cloud-upload-file
http:
multipart:
max-file-size: 20Mb # Max file size,默认1M
max-request-size: 20Mb # Max request size,默认10M
eureka:
client:
serviceUrl:
defaultZone: http://user:123456@localhost:8761/eureka
instance:
prefer-ip-address: true
#####################################################################################################
# 打印日志
logging:
level:
root: INFO
com.springms: DEBUG
com.netflix: debug
#####################################################################################################
pom.xml配置
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example.demo</groupId>
<artifactId>spring-cloud-upload-file</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>spring-cloud-upload-file</name>
<description>spring-cloud-upload-file</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.1.RELEASE</version>
</parent>
<properties>
<!-- 文件拷贝时的编码 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- 编译时的编码 -->
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<!-- jdk版本 -->
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- 客户端发现模块 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<!-- 监控和管理生产环境的模块 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- 用于热部署 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<!-- 版本依赖管理,故之后添加依赖无需指定version -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Camden.SR2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<!-- 用以为integration-test提供支持。 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
EurekaApplication类
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
/**
*
* 简单文件上传微服务,并加入 zuul 微服务后用 zuul 微服务地址采取curl或者页面点击实现文件上传。
*
* 提供给 spring-cloud-upload-file 文件上传微服务用的。
*
* 注意 EnableZuulProxy 注解能注册到 eureka 服务上,是因为该注解包含了 eureka 客户端的注解,该 EnableZuulProxy 是一个复合注解。
*
* @EnableZuulProxy --> { @EnableCircuitBreaker、@EnableDiscoveryClient } 包含了 eureka 客户端注解,同时也包含了 Hystrix 断路器模块注解。
*
*/
@EnableZuulProxy
@SpringBootApplication //开启启动程序入口类
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}
}
application.yml配置
server:
port: 8040
spring:
application:
name: spring-cloud-zuul-api-gateway-upload
eureka:
client:
serviceUrl:
defaultZone: http://user:123456@localhost:8761/eureka
instance:
prefer-ip-address: true
zuul:
routes:
uploadfile:
path: /upload/**
serviceId: spring-cloud-upload-file #反向代理到这个服务
#####################################################################################################
# 打印日志
logging:
level:
root: INFO
com.springms: DEBUG
com.netflix: debug
#####################################################################################################
#####################################################################################################
ribbon:
ConnectTimeout: 3000
ReadTimeout: 60000
#####################################################################################################
#####################################################################################################
# 解决第一次请求报超时异常的方案,因为 hystrix 的默认超时时间是 1 秒,因此请求超过该时间后,就会出现页面超时显示 :
#
# 这里就介绍大概三种方式来解决超时的问题,解决方案如下:
#
# 第一种方式:将 hystrix 的超时时间设置成 60000 毫秒,因为文件上传需要的超时时间稍微长一点点
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 60000
#
# 或者:
# 第二种方式:将 hystrix 的超时时间直接禁用掉,这样就没有超时的一说了,因为永远也不会超时了
# hystrix.command.default.execution.timeout.enabled: false
#
# 或者:
# 第三种方式:索性禁用feign的hystrix支持
# feign.hystrix.enabled: false ## 索性禁用feign的hystrix支持
# 超时的issue:https://github.com/spring-cloud/spring-cloud-netflix/issues/768
# 超时的解决方案: http://stackoverflow.com/questions/27375557/hystrix-command-fails-with-timed-out-and-no-fallback-available
# hystrix配置: https://github.com/Netflix/Hystrix/wiki/Configuration#execution.isolation.thread.timeoutInMilliseconds
#####################################################################################################
pom.xml配置
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example.demo</groupId>
<artifactId>spring-cloud-zuul-api-gateway-upload</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>spring-cloud-zuul-api-gateway-upload</name>
<description>spring-cloud-zuul-api-gateway-upload</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.1.RELEASE</version>
</parent>
<properties>
<!-- 文件拷贝时的编码 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- 编译时的编码 -->
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<!-- jdk版本 -->
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- API网关模块 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
<!-- 客户端发现模块,由于文档说 Zuul 的依赖里面不包括 eureka 客户端发现模块,所以这里还得单独添加进来 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<!-- 用于热部署 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<!-- 版本依赖管理,故之后添加依赖无需指定version -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Camden.SR2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<!-- 用以为integration-test提供支持。 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
启动spring-cloud-upload-file和spring-cloud-zuul-api-gateway-upload