spring-boot - Spring Cloud Gateway 未返回下游服务给出的正确响应代码(用于文件上传)
问题描述
我有一个简单的文件上传下游服务。示例代码
@RestController
@RequestMapping("/file")
public class FileController {
@PostMapping("/upload")
public ResponseEntity<?> uploadFile(@RequestParam("file") MultipartFile file,
@RequestParam(value = "delay", required = false, defaultValue = "0") int delay) throws Exception {
System.out.println(String.join(System.getProperty("line.separator"),
"File Name => " + file.getOriginalFilename(),
"File Size => " + file.getSize() + "bytes",
"File Content Type => " + file.getContentType()));
TimeUnit.MILLISECONDS.sleep(delay);
return ResponseEntity.ok(file.getName() + " uploaded");
}
}
如果有 a 则返回CustomExceptionHandler
a :BAD_REQUEST
MultipartException
@Configuration
@ControllerAdvice
public class CustomExceptionHandler {
@ExceptionHandler(MultipartException.class)
public ResponseEntity<String> handleMultipartException(MultipartException ex) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ex.getMessage());
}
}
application.yml 中的大小限制为 10MB:
spring:
servlet:
multipart:
max-file-size: 10MB
max-request-size: 10MB
当我尝试通过spring cloud gateway访问相同的内容时,我得到以下结果:
日志显示如下:
2019-11-08 00:36:10.797 ERROR 21904 --- [ctor-http-nio-2] a.w.r.e.AbstractErrorWebExceptionHandler : [86e57f7e] 500 Server Error for HTTP POST "/product-service/file/upload"
reactor.netty.http.client.PrematureCloseException: Connection has been closed BEFORE response, while sending request body
请注意,网关配置为接收大文件大小,RequestSize
全局过滤器设置为超过 10MB。
如何获得与下游服务提供的相同响应代码?
另外,我检查了传统的 Zuul,我500
也得到了一个错误。
对于网关,对于这种特殊情况,我知道我们可以使用RequestSize
过滤器,现在网关将返回错误代码,但是我们必须事先识别所有预期的路由。
此外,API 中的其他验证,如授权等,也会有同样的问题。由于这些验证而产生的响应代码不会向上传播。
示例代码 spring-cloud-gateway/product-service/eureka - https://github.com/dhananjay12/spring-cloud/tree/master/spring-routing
解决方案
您可以尝试直接通过文件体积的非限制而不通过 getway 吗?尝试属性的值 -1 :
要上传文件的 MS 的属性文件
spring.servlet.multipart.max-file-size =-1
spring.servlet.multipart.max-request-size =-1
如果它很好,它可能会给 zuul 代理的功能区套接字大小带来问题,有针对这种情况的属性通知,如下:
getway 的属性文件:
ribbon.eager-load.enabled=true
hystrix.command.default.execution.timeout.enabled=false
hystrix.command.default.execution.isolation.strategy=THREAD
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=3999996
ribbon.ConnectTimeout=999999
ribbon.ReadTimeout=999999
ribbon.SocketTimeout=999999
zuul.host.socket-timeout-millis=999999
zuul.host.connect-timeout-millis=999999
zuul.sensitiveHeaders=Cookie,Set-Cookie
推荐阅读
- laravel - 自定义刀片指令中的缓存问题 - Laravel
- pepper - Pepper Development 兼容性和版本
- javascript - 按文本选择链接(完全匹配)并替换 href
- vue.js - Vue Vuetify:无效的道具:道具“值”的自定义验证器检查失败。发现在--->
- javascript - 如何在 mapbox GL JS 上按日期范围过滤数据?
- python - 如何将嵌套字典的值分配给python中的单独变量?
- python - 编写递归函数来计算编号。图表
- python - 尝试在 Windows 10 中打开现有的命名管道 - errno 22,无效参数,但为什么呢?
- javascript - 按下按钮后如何使某些获取数据出现。使用 JavaScript 和 HTML
- android - GPS位置在本机反应中波动