Java 根据控制器更改文件大小限制(maxUploadSize)

Java 根据控制器更改文件大小限制(maxUploadSize),java,spring-mvc,upload,Java,Spring Mvc,Upload,我有一个SpringMVCweb,有两个不同的页面,它们有不同的表单来上传不同的文件。其中一个应具有2MB的限制,而另一个应具有50MB的限制 现在,我的app-config.xml中存在以下限制: <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- one of the properties avail

我有一个SpringMVCweb,有两个不同的页面,它们有不同的表单来上传不同的文件。其中一个应具有2MB的限制,而另一个应具有50MB的限制

现在,我的app-config.xml中存在以下限制:

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- one of the properties available; the maximum file size in bytes (2097152 B = 2 MB) -->
    <property name="maxUploadSize" value="2097152 "/>
</bean>
但很明显,这只控制2MB的限制。我如何对20MB进行限制? 我尝试了以下解决方案:,它在运行时更新了限制。但是,这会为每个会话和每个控制器更新它。因此,如果一个用户正在上载第一个表单的文件,那么另一个用户在第二个表单中使用上载应该具有第一个表单的限制


有什么帮助吗?谢谢

这就是实现的方法:重写
DispatcherServlet
类。示例可能如下所示:

public class CustomDispatcherServlet extends DispatcherServlet {

    private Map<String, MultipartResolver> multipartResolvers;

    @Override
    protected void initStrategies(ApplicationContext context) {
            super.initStrategies(context);
            initMultipartResolvers(context);
    }

    private void initMultipartResolvers(ApplicationContext context) {
            try {
                    multipartResolvers = new HashMap<>(context.getBeansOfType(MultipartResolver.class));
            } catch (NoSuchBeanDefinitionException ex) {
                    // Default is no multipart resolver.
                    this.multipartResolvers = Collections.emptyMap();
            }
    }

    @Override
    protected HttpServletRequest checkMultipart(HttpServletRequest request) throws MultipartException {
            if (this.multipartResolvers.isEmpty() && this.multipartResolvers.get(0).isMultipart(request)) {
                    if (request instanceof MultipartHttpServletRequest) {
                            logger.debug("Request is already a MultipartHttpServletRequest - if not in a forward, "
                                    + "this typically results from an additional MultipartFilter in web.xml");
                    } else {
                            MultipartResolver resolver = getMultipartResolverBasedOnRequest(request);
                            return resolver.resolveMultipart(request);
                    }
            }
            // If not returned before: return original request.
            return request;
    }

    private MultipartResolver getMultipartResolverBasedOnRequest(HttpServletRequest request) {
            // your logic to check the request-url and choose a multipart resolver accordingly.
            String resolverName = null;
            if (request.getRequestURI().contains("SomePath")) {
                    resolverName = "resolver1";
            } else {
                    resolverName = "resolver2";
            }
            return multipartResolvers.get(resolverName);
    }
}
公共类CustomDispatcherServlet扩展了DispatcherServlet{
私有映射多部分解析器;
@凌驾
受保护的策略(ApplicationContext上下文){
超级战略(背景);
initMultipartResolvers(上下文);
}
私有void initMultipartResolvers(ApplicationContext上下文){
试一试{
multipartResolvers=newhashmap(context.getBeansOfType(MultipartResolver.class));
}捕获(NoSuchBeanDefinitionException ex){
//默认情况下没有多部分解析器。
this.multipartResolvers=Collections.emptyMap();
}
}
@凌驾
受保护的HttpServletRequest checkMultipart(HttpServletRequest请求)引发MultipartException{
if(this.multipartResolvers.isEmpty()&&this.multipartResolvers.get(0.isMultipart(请求)){
if(MultipartTTPServletRequest的请求实例){
debug(“请求已经是multipartTTPServletRequest-如果不是在转发中,”
+“这通常是由web.xml中的附加多部分筛选器导致的”);
}否则{
MultipartResolver resolver=getMultipartResolverBasedOnRequest(请求);
返回resolver.resolveMultipart(请求);
}
}
//如果之前未返回:返回原始请求。
返回请求;
}
专用MultipartResolver getMultipartResolverBasedOnRequest(HttpServletRequest){
//检查请求url并相应地选择多部分解析器的逻辑。
字符串resolverName=null;
if(request.getRequestURI().contains(“SomePath”)){
resolverName=“resolver1”;
}否则{
resolverName=“resolver2”;
}
返回multipartResolvers.get(resolverName);
}
}
假设您已经在应用程序上下文中配置了多个多部分解析器(在示例代码中可能命名为“resolver1”和“resolver2”)

当然,当您在
web.xml
中配置
DispatcherServlet
时,您使用此类而不是Spring
DispatcherServlet


另一种方法:A也可以使用。只需重写该方法并自己查找所需的解析器。然而,这有一些如果和但是。使用前请查阅文档。

这里有一个优雅的解决方案


您可以修改应用程序的application.properties文件,根据需要更改最大上载大小。乍一看,这似乎不是最好的解决方案,但这取决于您的要求

public class BaseDispatcherServlet extends DispatcherServlet {
    @Override
    protected void doService(final HttpServletRequest request, final HttpServletResponse response) {
        CommonsMultipartResolver multipartResolver = (CommonsMultipartResolver) getMultipartResolver();
        if (requestURI.contains("uriWithLargeFileSize")) {
            multipartResolver.setMaxUploadSize(100 * 100L);
        }
    }
}                                                                                                                                                                                                                                                                                                                                                                                                                               
您可以为所有控制器设置具有最大上载大小的全局选项,并为特定控制器使用较低的值覆盖该选项

application.properties文件(Spring引导)

带支票的上传控制器

public void uploadFile(@RequestPart("file") MultipartFile file) {
    final long limit = 2 * 1024 * 1024;    // 2 MB
    if (file.getSize() > limit) {
        throw new MaxUploadSizeExceededException(limit);
    }
    StorageService.uploadFile(file);
}
如果文件大于2MB,您将在日志中看到此异常:

org.springframework.web.multipart.MaxUploadSizeExceededException: Maximum upload size of 2097152 bytes exceeded

作为Commons Fileupload的主要作者和维护者,我就您的用例提出以下建议:

  • 有两个FileUploadBase实例,一个最大大小为2MB,另一个最大大小为20MB。根据请求的详细信息(例如,通过查看URI),使用一个或另一个实例
  • 如果您不直接使用FileUpload(但是前面使用Spring、Struts或其他什么),那么很可能对FileUpload进行更改是不够的,因为前端不支持可能的新功能,至少最初不支持。在这种情况下,我建议您开始推动前端开发人员支持您的需求。通过为每个请求创建FileUploadBase实例,他们可以很容易地做到这一点。(这是一个轻量级对象,只要您不使用文件跟踪器或类似的高级功能,因此没有问题。)
  • 我已经准备好检查并可能接受您或其他人的补丁,这些补丁用谓词或类似的东西替换当前的maxUploadSize检查

Jochen

看看这个,我已经为这个功能提出了拉取请求-
public void uploadFile(@RequestPart("file") MultipartFile file) {
    final long limit = 2 * 1024 * 1024;    // 2 MB
    if (file.getSize() > limit) {
        throw new MaxUploadSizeExceededException(limit);
    }
    StorageService.uploadFile(file);
}
org.springframework.web.multipart.MaxUploadSizeExceededException: Maximum upload size of 2097152 bytes exceeded