坑了2小时,终于通过谷歌解决,需要配置tomcat的connector的MaxSwallowSize为-1(无限制)或者大于等于spring中单个请求的文件上传打大小,建议设置大于等于spring的配置,另外spring boot暂未提供该属性的自定义配置,需要手动创建tomcat来配置connector
1、创建tomcat的属性配置类TomcatProperties
/**
* 系统项目名称
* com.properties
* TomcatProperties.java
*
* 2017年12月14日-上午8:38:33
* 2017rejoiceFromJesus-版权所有
*
*/
package com.properties;
import javax.validation.Valid;
import javax.validation.constraints.Pattern;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
*
* TomcatProperties
*
* @author rejoice 948870341@qq.com
* @date 2017年12月14日 上午8:38:33
*
* @version 1.0.0
*
*/
@ConfigurationProperties(prefix=TomcatProperties.PREFIX)
public class TomcatProperties {
public static final String PREFIX = "tomcat";
@Valid
private Connector connector = new Connector();
public Connector getConnector() {
return connector;
}
public void setConnector(Connector connector) {
this.connector = connector;
}
/**
* connector
*
* @author rejoice 948870341@qq.com
* @date 2017年12月14日 上午8:44:19
*
* @version 1.0.0
*
*/
public static class Connector{
/**
* The maximum number of request body bytes (excluding transfer encoding overhead) that will be swallowed by Tomcat
* for an aborted upload. An aborted upload is when Tomcat knows that the request body is going to be ignored but the client still sends it.
* If Tomcat does not swallow the body the client is unlikely to see the response.
* If not specified the default of 2097152 (2 megabytes) will be used.
* A value of less than zero indicates that no limit should be enforced.
* Here the custom value is "50MB"
*/
@Pattern(regexp="^(\\d+)(MB)$",message="must start with number and end with MB")
private String maxSwallowSize = "50MB";
public String getMaxSwallowSize() {
return maxSwallowSize;
}
public void setMaxSwallowSize(String maxSwallowSize) {
this.maxSwallowSize = maxSwallowSize;
}
}
}
2、application.properties
#file-upload
#single file max size
spring.http.multipart.max-file-size=10MB
#single request max size
spring.http.multipart.max-request-size=100MB
#tomcat
#max-swallow-size: -1 or any other value lt 0, means unlimited;i suggest setting to spring.http.multipart.max-request-size
tomcat.connector.max-swallow-size=${spring.http.multipart.max-request-size}
3、WebConfig:自定义tomcat,配置tomcat的connector的maxSwallowSize
/**
* 系统项目名称
* com.conf
* WebConfig.java
*
* 2017年11月23日-下午5:02:35
* 2017rejoiceFromJesus-版权所有
*
*/
package com.config;
import java.util.Calendar;
import java.util.TimeZone;
import org.apache.coyote.http11.AbstractHttp11Protocol;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.embedded.tomcat.TomcatConnectorCustomizer;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.properties.TomcatProperties;
/**
*
* WebConfig
*
* @author rejoice 948870341@qq.com
* @date 2017年11月23日 下午5:02:35
*
* @version 1.0.0
*
*/
@Configuration
@EnableConfigurationProperties(TomcatProperties.class)
public class WebConfig extends WebMvcConfigurerAdapter{
@Autowired
private TomcatProperties tomcatProperties;
@Bean
public TomcatEmbeddedServletContainerFactory tomcatEmbedded() {
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
tomcat.addConnectorCustomizers((TomcatConnectorCustomizer) connector -> {
// connector other settings...
// configure maxSwallowSize
if ((connector.getProtocolHandler() instanceof AbstractHttp11Protocol<?>)) {
// -1 means unlimited, accept bytes
//conver MB to B
String maxSwallowSize = tomcatProperties.getConnector().getMaxSwallowSize();
Integer sizeB = Integer.parseInt(tomcatProperties.getConnector().getMaxSwallowSize().substring(0, maxSwallowSize.length()-2))*1024*1024;
((AbstractHttp11Protocol<?>) connector.getProtocolHandler()).setMaxSwallowSize(sizeB);
}
});
return tomcat;
}
@Bean
public ObjectMapper mapper(){
ObjectMapper mapper = new ObjectMapper();
mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
//mapper.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));
Calendar cal = Calendar.getInstance();
TimeZone timeZone = cal.getTimeZone();
mapper.setTimeZone(timeZone);
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
return mapper;
}
/*@Bean
public MappingJackson2HttpMessageConverter customJackson2HttpMessageConverter() {
MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
jsonConverter.setObjectMapper(mapper());
return jsonConverter;
}
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.clear();
converters.add(customJackson2HttpMessageConverter());
}*/
}
4、自定义错误信息:GlobalExceptionHandler
/**
* 系统项目名称
* com.common.exception
* GloabalExceptionHandler.java
*
* 2017年12月13日-下午4:11:16
* 2017rejoiceFromJesus-版权所有
*
*/
package com.common.exception;
import javax.servlet.http.HttpServletRequest;
import org.apache.tomcat.util.http.fileupload.FileUploadBase;
import org.apache.tomcat.util.http.fileupload.FileUploadBase.FileSizeLimitExceededException;
import org.apache.tomcat.util.http.fileupload.FileUploadBase.SizeLimitExceededException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.multipart.MultipartException;
/**
*
* GloabalExceptionHandler
*
* @author rejoice 948870341@qq.com
* @date 2017年12月13日 下午4:11:16
*
* @version 1.0.0
*
*/
@ControllerAdvice
public class GlobalExceptionHandler {
@ResponseStatus(value=HttpStatus.BAD_REQUEST)
@ExceptionHandler({ MultipartException.class})
@ResponseBody
public Object handleMultipartException(HttpServletRequest request, Throwable ex){
String message = "";
MultipartException mEx = (MultipartException)ex;
Throwable cause = ex.getCause().getCause();
if (cause instanceof SizeLimitExceededException){
SizeLimitExceededException flEx = (SizeLimitExceededException) cause;
float permittedSize = flEx.getPermittedSize() / 1024 / 1024;
message = "single request max size exceeds "+permittedSize+"MB";
} else if (cause instanceof FileSizeLimitExceededException){
FileSizeLimitExceededException flEx = (FileSizeLimitExceededException)mEx.getCause().getCause();
float permittedSize = flEx.getPermittedSize() / 1024 / 1024;
message = "single file max size exceeds "+permittedSize+"MB";
}else {
message = "Please contact your administrator: " + ex.getMessage();
}
return message;
}
}
5、实际效果:
image.png
参考文章
https://stackoverflow.com/questions/31605129/spring-file-upload-with-multipart-resolver-causes-connection-reset-when-file-is
https://www.mkyong.com/spring-boot/spring-boot-configure-maxswallowsize-in-embedded-tomcat/
http://blog.csdn.net/funchs/article/details/50978576
网友评论