正常情況下,我們使用普通的響應層(如SpringMVC)框架,是可以上傳任意大小的文件的。在SpringMVC,是通過其“multipartResolver”這個Bean的設置,指定其“MaxUploadSize”參數的具體數字,來控制上傳文件的具體大小的。
Zuul作爲服務網關的情況下,也是可以上傳文件的,Zuul在做文件上傳的時候,只支持小文件的上傳(1M以內),大文件(10M以上)上傳會則報錯,這是Zuul對文件上傳的默認的設置。
新建一個上傳項目:ms-zuul-fileupload
1.pom文件:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
2.修改配置文件:
server:
port: 8009
spring:
application:
name: ms-zuul-fileupload
servlet:
multipart:
max-file-size: 500Mb # Max file size,默認1M
max-request-size: 1000Mb # Max request size,默認10M
eureka:
client:
healthcheck:
enabled: true
serviceUrl:
defaultZone: http://ljf:123@localhost:8761/eureka
instance:
prefer-ip-address: true
instance-id: ${spring.application.name}:${spring.cloud.client.ipAddress}:${spring.application.instance_id:${server.port}}
turbine:
aggregator:
clusterConfig: ljf-turbine,ljf-feigin
app-config: ms-hystrix-consumer,ms-fegin-consumer
cluster-name-expression: metadata['cluster']
combine-host-port: true
#設置查看指標
management:
endpoint:
health:
show-details: always
endpoints:
web:
exposure:
include: "*"
3.controller:
package com.ljf.weifuwu.springcloud.fileupload.zuul.controller;
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;
import java.io.File;
import java.io.IOException;
@Controller
public class FileUploadController {
/**
* 上傳文件
* ps.該示例比較簡單,沒有做IO異常、文件大小、文件非空等處理
* @param file 待上傳的文件
* @return 文件在服務器上的絕對路徑
* @throws IOException IO異常
*/
@RequestMapping(value = "/zuul-Upload", method = RequestMethod.POST)
public @ResponseBody String handleFileUpload(@RequestParam(value = "zuulFile", required = true) MultipartFile file) throws IOException {
System.out.println("上傳功能,controller!!!!");
byte[] bytes = file.getBytes();
File fileToSave = new File(file.getOriginalFilename());
FileCopyUtils.copy(bytes, fileToSave);
System.out.println("文件上傳存儲路徑:"+fileToSave.getAbsolutePath());
return fileToSave.getAbsolutePath();
}
}
4.啓動類:
package com.ljf.weifuwu.springcloud.fileupload.zuul;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
/**
* Hello world!
*
*/
@SpringBootApplication
@EnableEurekaClient
public class ZuulFileUploadApp
{
public static void main( String[] args )
{
SpringApplication.run(ZuulFileUploadApp.class, args);
System.out.println( "zuul-fileupload啓動起來了!" );
}
}
5.index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>zuul實現上傳文件頁面</title>
</head>
<body>
<div style="width:800px;height:300px;border:1px solid red">
<span>
<form method="POST" enctype="multipart/form-data" action="/zuul-Upload">
<span style="width:100px;"> 請選擇上傳的文件</span>:<span style="width:300px;"><input type="file" name="zuulFile"></span>
<span>提交: <input type="submit" value="Upload"></span>
</form>
</span>
</div>
</body>
</html>
6.啓動服務:ms-eureka-center(8761)、ms-zuul-consumer(8008)、ms-zuul-fileupload(8009)
6.直接訪問ms-zuul-fileupload進行訪問:
6.1上傳一個小文件871kb
上傳成功!!!
7.通過zuul進行上傳
在index.hmtl中的action跳轉路徑改爲:http://localhost:8008/user-fileupload/zuul-Upload
在啓動類中加: multipartConfigElement()方法
package com.ljf.weifuwu.springcloud.fileupload.zuul;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import javax.servlet.MultipartConfigElement;
/**
* Hello world!
*
*/
@SpringBootApplication
@EnableEurekaClient
public class ZuulFileUploadApp
{
/**
* 文件上傳配置
*
* @return
*/
@Bean
public MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory();
// 單個數據大小
factory.setMaxFileSize("500000KB"); // KB,MB
/// 總上傳數據大小
factory.setMaxRequestSize("1000000KB");
return factory.createMultipartConfig();
}
public static void main( String[] args )
{
SpringApplication.run(ZuulFileUploadApp.class, args);
System.out.println( "zuul-fileupload啓動起來了!" );
}
}
還是上傳不成功,需要對網關項目進行配置,在網關項目ms-zuul-consumer,添加要訪問的項目
在啓動類上加配置: multipartConfigElement()方法
package com.ljf.weifuwu.springcloud.zuul;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.context.annotation.Bean;
import javax.servlet.MultipartConfigElement;
/**
* Hello world!
*
*/
@SpringBootApplication
@EnableZuulProxy
public class ZuulConsumerApp
{
/**
* 文件上傳配置
*
* @return
*/
@Bean
public MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory();
// 單個數據大小
factory.setMaxFileSize("500000KB"); // KB,MB
/// 總上傳數據大小
factory.setMaxRequestSize("1000000KB");
return factory.createMultipartConfig();
}
public static void main(String args[]){
SpringApplication.run(ZuulConsumerApp.class, args);
System.out.println( "zuul啓動起來了!" );
}
}
再次啓動:然後上傳: 頁面提示超時錯誤,但是後端已經上傳成功!
通過上面的報錯“microservice-file-upload timed-out and no fallback available.”我們可以瞭解到,主要原因還是因爲請求處理超時,並且沒有響應我們在上傳大文件時,會因爲上傳時間過長,而導致hystrix認爲該請求無響應,最終給客戶端反饋了超時並沒有響應的異常,我們只需在網關項目ms-zuul-consumer的application的配置文件中,提升hystrix的超時時間即可:
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 60000
ribbon:
ConnectTimeout: 3000
ReadTimeout: 60000
如截圖:
再次上傳後:可以看到頁面的提示了,返回了正確的上傳路徑。