undertow容器处理上传文件过大异常
序前端反馈上传过大的文件,没有返回存储信息。一、场景说明我这里是springCloud2020.0.2+springBoot2.4.5,spring原生微服务,没有依赖第三方的组件。容器用的是undertow,这里先说下用这个容器有一个坑,后面说。二、配置情况我这里是配了:1、配置了openFeign的传参限制#feign配置feign:httpclient:connection-timeout:
序
前端反馈上传过大的文件,没有返回存储信息。
一、场景说明
我这里是springCloud2020.0.2+springBoot2.4.5,spring原生微服务,没有依赖第三方的组件。容器用的是undertow,这里先说下用这个容器有一个坑,后面说。
二、配置情况
我这里是配了:
1、配置了openFeign的传参限制
#feign配置
feign:
httpclient:
connection-timeout: 30000
#请求压缩
compression:
request:
enabled: true
min-request-size: 2048
response:
enabled: true
max-request-size: 204800000
2、配置了上传文件的大小限制
#设置时间格式
spring:
#文件上传配置
servlet:
multipart:
enabled: true # 是否支持多部分上传。
maxFileSize: 20MB # 最大支持文件上传的大小
maxRequestSize: 200MB # 支持请求最大文件上传的大小
3、配置了容器的http请求的传参限制
#容器中间件undertow配置
server:
shutdown: graceful # 优雅停机
undertow:
accesslog:
dir: logs
enabled: false
buffer-size: 1024
direct-buffers: true
max-http-post-size: -1B
threads:
io: 8
worker: 256
设置为-1B表示不限制
三、统一异常处理类
package com.fillersmart.fsihouse.thirdweb.exception;
import com.fillersmart.fsihouse.data.common.api.ResponseCodeI18n;
import com.fillersmart.fsihouse.data.core.Result;
import com.fillersmart.fsihouse.data.core.ResultGenerator;
import io.undertow.server.handlers.form.MultiPartParserDefinition;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.fileupload.FileUploadBase;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.MultipartException;
/**
* 第三方服务接口层统一异常处理
*
* @author zhengwen
**/
@Slf4j
@RestControllerAdvice
public class GloabExceptionHandler {
/**
* 处理文件上传大小超限制
*
* @param exception
* @return
*/
@ExceptionHandler(value = MultipartException.class)
public Result<?> fileUploadExceptionHandler(MultipartException exception) {
Throwable throwable = exception.getRootCause();
if (throwable instanceof FileUploadBase.FileSizeLimitExceededException) {
log.error("上传文件过大", exception);
return ResultGenerator.genFailResult(ResponseCodeI18n.UPLOAD_FILE_ALONE_GT_MAX_SIZE.getMsg());
}
if (throwable instanceof FileUploadBase.SizeLimitExceededException) {
log.error("总上传文件过大", exception);
return ResultGenerator.genFailResult(ResponseCodeI18n.UPLOAD_FILE_GT_TOTAL_MAX_SIZE.getMsg());
}
//容器undertow文件上传过大异常支持
if (throwable instanceof MultiPartParserDefinition.FileTooLargeException) {
log.error("上传文件过大", exception);
return ResultGenerator.genFailResult(ResponseCodeI18n.UPLOAD_FILE_ALONE_GT_MAX_SIZE.getMsg());
}
log.error("上传文件异常", exception);
return ResultGenerator.genFailResult(ResponseCodeI18n.UPLOAD_FILE_EXCEPTION.getMsg());
}
}
这里使用spring3.2开始提供的新注解@RestControllerAdvice配合@ExceptionHandler注解,对@RestControllerAdvice注解使用详解感兴趣的,可以自行学习,这里不展开讲。
上面有注释的FileTooLargeException异常判断就是对undertow容器的支持,不然,容器会抛出异常:io.undertow.server.handlers.form.MultiPartParserDefinition$FileTooLargeException: UT000054: The maximum size 20971520 for an individual file in a multipart request was exceeded。不会被springMVC的异常拦截机制catch到,这应该是容器的问题,如果用tomcat容器就没有这个问题。
最后说下我这个异常处理类所在的服务,我这个异常处理在接口层,也就网关转发的第一层。本来最开始我想把这个统一处理类直接放到网关层的,考虑到实际情况:
第一我放了后没有成功
原因:接口层没有继续往上throw异常。
第二考虑到后面其他平台可能有交互不走我们的网关,
所以最终就放在了接口层,向上返回的组织成我们内部用统一封装对象,其实里面就是一个code、msg、data。
网上之前百度了都说是undertow的问题,但是没有给出解决方案,建议不要用undertow,但是undertow的性能优势在那里,我不想抛弃,所以硬着头皮跟,最后找到了这个办法,其实看到控制台打印的异常,也是可以直接就处理了。希望可以帮到大家。
更多推荐
所有评论(0)