如何在运行时更改spring.http.multipart.maxFileSize?

时间:2017-11-20 13:42:32

标签: java spring spring-boot multipart

application.properties我有:

spring.http.multipart.maxFileSize
spring.http.multipart.maxRequestSize

但我想有可能在没有应用程序重启的情况下更改此属性。

有可能吗?

1 个答案:

答案 0 :(得分:4)

在深入挖掘源代码后,我找到了一种方法StandardServletMultipartResolver

StandardServletMultipartResolverHttpServletRequestStandardMultipartHttpServletRequest包装在一起,request.getParts()使用MultipartConfigElement的标准servlet api实现来处理多部分请求。在内部,此方法使用ServletRegistrationBean,在调度程序servlet的注册期间由MultipartConfigElement设置。我们对ServletRegistrationBean感兴趣,因为它包含我们感兴趣的属性。

默认情况下MultipartConfigElementMultipartAutoConfiguration获取MultipartConfigElementMultipartConfigurationContext的默认实现不允许修改其属性,因此我们需要扩展此类以添加此类功能。进一步的实现取决于您是要根据每个请求修改参数还是为整个应用程序不时修改参数。

每个请求基础

UpdateMultipartConfigurationFilter存储特定请求的配置。 UpdatableMultipartConfigElement为给定请求设置多部分属性。如果提供,public class MultipartConfigurationContext { private static ThreadLocal<Integer> maxFileSize = new ThreadLocal<>(); public static void setMaxFileSize(Integer val) { maxFileSize.set(val); } public static Integer getMaxFileSize() { return maxFileSize.get(); } public static void clear() { maxFileSize.set(null); } } public class UpdatableMultipartConfigElement extends MultipartConfigElement { private final long maxFileSize; public UpdatableMultipartConfigElement(String location, long maxFileSize, long maxRequestSize, int fileSizeThreshold) { super(location, maxFileSize, maxRequestSize, fileSizeThreshold); this.maxFileSize = maxFileSize; } @Override public long getMaxFileSize() { return MultipartConfigurationContext.getMaxFileSize() == null ? maxFileSize : MultipartConfigurationContext.getMaxFileSize(); } } public class UpdateMultipartConfigurationFilter extends OncePerRequestFilter implements Ordered { // this filter must be before OrderedHiddenHttpMethodFilter public static final int ORDER = FilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER - 20000; @Override public int getOrder() { return ORDER; } @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { // gets file size from request if present and sets it to MultipartConfigurationContext MultipartConfigurationContext.setMaxFileSize(150_000); filterChain.doFilter(request, response); MultipartConfigurationContext.clear(); } } @Configuration @EnableConfigurationProperties(MultipartProperties.class) public class MultipartConfiguration { private final MultipartProperties multipartProperties; public MultipartConfiguration(MultipartProperties multipartProperties) { this.multipartProperties = multipartProperties; } @Bean public MultipartConfigElement multipartConfigElement() { MultipartConfigElement multipartConfigElement = multipartProperties.createMultipartConfig(); return new UpdatableMultipartConfigElement(multipartConfigElement.getLocation(), multipartConfigElement.getMaxFileSize(), multipartConfigElement.getMaxRequestSize(), multipartConfigElement.getFileSizeThreshold()); } @Bean public UpdateMultipartConfigurationFilter updateMultipartConfigurationFilter() { return new UpdateMultipartConfigurationFilter(); } } 会使用此信息。

UpdatableMultipartConfigElement

全球

public class UpdatableMultipartConfigElement extends MultipartConfigElement { private volatile long maxFileSize = -1; public UpdatableMultipartConfigElement(String location, long maxFileSize, long maxRequestSize, int fileSizeThreshold) { super(location, maxFileSize, maxRequestSize, fileSizeThreshold); } @Override public long getMaxFileSize() { return maxFileSize == -1 ? super.getMaxFileSize() : maxFileSize; } public void setMaxFileSize(long maxFileSize) { this.maxFileSize = maxFileSize; } } @Configuration @EnableConfigurationProperties(MultipartProperties.class) public class MultipartConfiguration { private final MultipartProperties multipartProperties; public MultipartConfiguration(MultipartProperties multipartProperties) { this.multipartProperties = multipartProperties; } @Bean public MultipartConfigElement multipartConfigElement() { MultipartConfigElement multipartConfigElement = multipartProperties.createMultipartConfig(); return new UpdatableMultipartConfigElement(multipartConfigElement.getLocation(), multipartConfigElement.getMaxFileSize(), multipartConfigElement.getMaxRequestSize(), multipartConfigElement.getFileSizeThreshold()); } } @RestController public class ConfigurationController { @Autowired private UpdatableMultipartConfigElement updatableMultipartConfigElement; @RequestMapping("/configuration") public void configuration(@RequestParam("maxFileSize") long maxFileSize) { updatableMultipartConfigElement.setMaxFileSize(maxFileSize); } } 存储可以使用rest api调用在运行时更新的信息。

{{1}}