非 Spring MVC 应用程序中的 MultipartFilter

MultipartFilter in a non-Spring MVC application

在 Java servlet (2.5) in Tomcat 6 中,我们使用 Spring 和 Spring security 3 但没有 Spring MVC。我们尝试实现 CSRF 安全性,因此我们将 _csrf 标记添加到我们所有的表单中。对于文件上传,我们将 org.springframework.web.multipart.support.MultipartFilter 添加到我们的 web.xml,并且还修复了 commons-fileupload 依赖项。

我们可以看到请求已被解析和包装,但是 spring 安全性也在再次包装请求,所以我们不能再访问多部分数据了,是吗?我尝试将请求对象转换为 MultipartHttpServletRequest 但失败了。 Internet 上的所有示例都显示了如何访问 Spring MVC 控制器中的文件项。我在这里有点迷路了。

所有这些包装器都是从标准 ServletRequestWrapper interface. Just cast to it, obtain the wrapped request via getRequest() 方法扩展而来并对其进行测试。

如果它实际上返回了另一个 ServletRequestWrapper 实现,您甚至可以循环执行它。

public static <R extends ServletRequest> R unwrap(ServletRequest request, Class<R> type) {
    ServletRequest current = request;

    while (!type.isInstance(current) && current instanceof ServletRequestWrapper) {
        current = ((ServletRequestWrapper) current).getRequest();
    }

    return type.isInstance(current) ? type.cast(current) : null;
}

用法:

MultipartHttpServletRequest multipartRequest = unwrap(request, MultipartHttpServletRequest.class);
// ...

关于奖励问题:您的 Web 应用程序的运行时类路径包含某个地方的 Servlet 3.0+ API。如果这不是本意,那么它很可能只是一个肮脏的运行时类路径。只需清理它即可摆脱 Servlet 3.0+ 库。 webapp 的运行时类路径涵盖的文件夹是 a.o。 WAR 的 /WEB-INF/lib、服务器的 /lib 和 JRE 的 /lib.

虽然我喜欢 BalusC 更好地解决它的方式(使用 while 循环与递归),但我认为值得一提的是

import org.springframework.web.util.WebUtils;
...
WebUtils.getNativeRequest(request, MultipartHttpServletRequest.class);

做同样的事情,但只是递归,但在一个得到很好支持的 Lib-Class :)