【问题标题】:How to change spring.http.multipart.maxFileSize in Runtime?如何在运行时更改 spring.http.multipart.maxFileSize?
【发布时间】:2017-11-20 13:42:32
【问题描述】:

application.properties 我有:

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

但我希望能够在不重新启动应用程序的情况下更改此属性。

有可能吗?

【问题讨论】:

标签: java spring spring-boot multipart


【解决方案1】:

在挖掘源代码后,我找到了一种方法来处理StandardServletMultipartResolver

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

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

根据请求

MultipartConfigurationContext 存储特定请求的配置。 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 存储可以在运行时使用 rest api 调用更新的信息。

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);
    }

}

【讨论】:

  • 我保证明天试试这个解决方案
  • 第二种解决方案对我有用。非常感谢!
猜你喜欢
  • 1970-01-01
  • 2012-01-12
  • 2010-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多