2014-04-22 55 views
5

如何將多部分配置添加到使用帶有RequestMapping註解的方法的控制器的spring mvc應用程序中?在Spring MVC上使用Servlet 3.0的MultipartConfig

背景:

我想啓用CSRF保護等方面都增加了安全性:在我的Spring配置CSRF標記。我有一個帶有RequestMapping註解的方法的控制器類,用於上傳文件。我也遵循caveat instructions多部分,因此我在安全過濾器上面添加了多部分過濾器。當我在添加csrf標籤後嘗試上傳文件時,我得到了一個關於缺少getParts()方法的異常。快速谷歌突出這是由於使用基於servlet 2.5規範的碼頭版本。我將jetty-maven-plugin升級到8.1.14.v20131031,並嘗試再次上傳。導致:

org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request; nested exception is java.lang.IllegalStateException: No multipart config for servlet 
     at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.<init>(StandardMultipartHttpServletRequest.java:68) 
     at org.springframework.web.multipart.support.StandardServletMultipartResolver.resolveMultipart(StandardServletMultipartResolver.java:58) 
     at org.springframework.web.multipart.support.MultipartFilter.doFilterInternal(MultipartFilter.java:110) 

我在哪裏把多部分配置爲XML安裝?所有文檔都表示要在web.xml中的特定servlet的servlet標記中添加multipart-config。儘管我的應用程序只有一個servlet。所以我把它添加到了這一點,但我仍然遇到同樣的問題。

<servlet> 
    <servlet-name>SpringDispatcher</servlet-name> 
    <servlet-class>org.springframework.web.servlet.DispatcherServlet 
    </servlet-class> 
    <multipart-config> 
     <location>/tmp</location> 
     <max-file-size>20848820</max-file-size> 
     <max-request-size>418018841</max-request-size> 
     <file-size-threshold>1048576</file-size-threshold> 
    </multipart-config> 
    <init-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>/WEB-INF/spring/servlet-context.xml 
     </param-value> 
    </init-param> 
    <load-on-startup>10</load-on-startup> 
</servlet> 

我也是在web.xml中的頂部更新架構位置在Servlet規範的3.0版本,以點帶面,從http://www.mkyong.com/web-development/the-web-xml-deployment-descriptor-examples/來源。

任何幫助?

編輯:增加了羅布以下萊利:

的web.xml

<?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 
    version="3.0"> 

    <context-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>classpath:/spring/webapp.xml</param-value> 
    </context-param> 

    <context-param> 
     <param-name>spring.profiles.default</param-name> 
     <param-value>OracleDB,common</param-value> 
    </context-param> 

    <listener> 
     <listener-class>org.springframework.web.context.ContextLoaderListener 
     </listener-class> 
    </listener> 

    <listener> 
     <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher 
     </listener-class> 
    </listener> 

    <servlet> 
     <servlet-name>SpringDispatcher</servlet-name> 
     <servlet-class>org.springframework.web.servlet.DispatcherServlet 
     </servlet-class> 
     <multipart-config> 
      <location>/tmp</location> 
      <max-file-size>20848820</max-file-size> 
      <max-request-size>418018841</max-request-size> 
      <file-size-threshold>1048576</file-size-threshold> 
     </multipart-config> 
     <init-param> 
      <param-name>contextConfigLocation</param-name> 
      <param-value>/WEB-INF/spring/servlet-context.xml 
      </param-value> 
     </init-param> 
     <load-on-startup>10</load-on-startup> 
    </servlet> 

    <servlet-mapping> 
     <servlet-name>SpringDispatcher</servlet-name> 
     <url-pattern>/</url-pattern> 
    </servlet-mapping> 

    <filter> 
     <filter-name>MultipartFilter</filter-name> 
     <filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class> 
    </filter> 

    <filter-mapping> 
     <filter-name>MultipartFilter</filter-name> 
     <url-pattern>/*</url-pattern> 
    </filter-mapping> 

    <filter> 
     <filter-name>springSecurityFilterChain</filter-name> 
     <filter-class>org.springframework.web.filter.DelegatingFilterProxy 
     </filter-class> 
    </filter> 

    <filter-mapping> 
     <filter-name>springSecurityFilterChain</filter-name> 
     <url-pattern>/*</url-pattern> 
    </filter-mapping> 

    <filter> 
     <filter-name>sitemesh</filter-name> 
     <filter-class>com.opensymphony.module.sitemesh.filter.PageFilter</filter-class> 
    </filter> 

    <filter-mapping> 
     <filter-name>sitemesh</filter-name> 
     <url-pattern>/*</url-pattern> 
    </filter-mapping> 

    <filter> 
     <filter-name>characterEncodingFilter</filter-name> 
     <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> 
     <init-param> 
      <param-name>encoding</param-name> 
      <param-value>UTF-8</param-value> 
     </init-param> 
     <init-param> 
      <param-name>forceEncoding</param-name> 
      <param-value>true</param-value> 
     </init-param> 
    </filter> 

    <filter-mapping> 
     <filter-name>characterEncodingFilter</filter-name> 
     <url-pattern>/*</url-pattern> 
    </filter-mapping> 

    <filter> 
     <filter-name>XSS</filter-name> 
     <filter-class>com.mycompany.CrossScriptingFilter</filter-class> 
    </filter> 

    <filter-mapping> 
     <filter-name>XSS</filter-name> 
     <url-pattern>/*</url-pattern> 
    </filter-mapping> 

    <session-config> 
     <session-timeout>10</session-timeout> 
    </session-config> 

    <resource-ref> 
     <description>Core Datasource</description> 
     <res-ref-name>jdbc/coreDataSource</res-ref-name> 
     <res-type>javax.sql.DataSource</res-type> 
     <res-auth>Container</res-auth> 
    </resource-ref> 

    <resource-ref> 
     <description>Location Datasource</description> 
     <res-ref-name>jdbc/locationDataSource</res-ref-name> 
     <res-type>javax.sql.DataSource</res-type> 
     <res-auth>Container</res-auth> 
    </resource-ref> 

    <error-page> 
     <!-- Missing login --> 
     <error-code>401</error-code> 
     <location>/WEB-INF/views/errorPage.jsp</location> 
    </error-page> 
    <error-page> 
     <!-- Forbidden directory listing --> 
     <error-code>403</error-code> 
     <location>/WEB-INF/views/errorPage.jsp</location> 
    </error-page> 
    <error-page> 
     <!-- Missing resource --> 
     <error-code>404</error-code> 
     <location>/WEB-INF/views/errorPageNotFound.jsp</location> 
    </error-page> 
    <error-page> 
     <!-- Uncaught exception --> 
     <error-code>500</error-code> 
     <location>/WEB-INF/views/errorPage.jsp</location> 
    </error-page> 
    <error-page> 
     <!-- Unsupported servlet method --> 
     <error-code>503</error-code> 
     <location>/WEB-INF/views/errorPage.jsp</location> 
    </error-page> 

</web-app> 

的servlet-context.xml的

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:util="http://www.springframework.org/schema/util" xmlns:security="http://www.springframework.org/schema/security" 
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd 
     http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd 
     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd 
     http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd"> 

    <mvc:annotation-driven /> 

    <mvc:resources mapping="/resources/**" location="/resources/" /> 
    <mvc:resources mapping="/images/**" location="file:${fileSystemStore.fileSystemStorageLocation}"/> 

    <context:component-scan base-package="com.mycompany.console.*" /> 

    <mvc:interceptors> 
     <bean class="com.mycompany.security.ChangePasswordInterceptor" /> 
    </mvc:interceptors> 

    <security:global-method-security 
     secured-annotations="enabled" jsr250-annotations="enabled" 
     pre-post-annotations="enabled" proxy-target-class="true" /> 

    <bean id="viewResolver" 
     class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
     <property name="viewClass" 
      value="org.springframework.web.servlet.view.JstlView" /> 
     <property name="prefix" value="/WEB-INF/views/" /> 
     <property name="suffix" value=".jsp" /> 
     <property name="contentType" value="text/html;charset=UTF-8" /> 
    </bean> 

    <bean id="filterMultipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> 
     <property name="maxUploadSize" value="100000000"/> 
    </bean> 

    <bean id="messageSource" 
     class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> 
     <property name="basenames"> 
      <list> 
       <value>classpath:language</value> 
       <value>classpath:language_additions</value> 
       <value>classpath:formats</value> 
      </list> 
     </property> 
     <property name="defaultEncoding" value="UTF-8" /> 
    </bean> 

    <bean id="localeResolver" class="com.mycompany.locale.SessionLocaleResolver"/> 

</beans> 

回答

9

我相信您有相關SPR-11373問題。具體來說,Servlet規範並不清楚在Filter中執行多部分解析時會發生什麼情況。

您是否嘗試過使用commons-fileupload來代替?這可能是您的最佳選擇。首先添加以下依賴項:

<dependency> 
    <groupId>commons-fileupload</groupId> 
    <artifactId>commons-fileupload</artifactId> 
    <version>1.2.2</version> 
</dependency> 

接下來確保您在根應用程序上下文中具有以下bean定義。

<bean id="filterMultipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> 
<property name="maxUploadSize" value="100000000"/> 
</bean> 

你可以找到既公地上傳(喜歡這個解決方案)和我已經使用進口和bean定義上SEC-2471

+0

使用使用allowCasualMultipartParsing tomcat的一個完整的工作示例。 – edwardmlyte

+0

更正,我使用擴展CommonsMultipartResolver的類。但直接嘗試與CMR直接導致相同的錯誤。 (單獨問題:關於csrf的警告文檔需要更新,因爲它指示在多部分過濾器映射中使用「servlet-name」標記,但在您的示例中,我看到您使用了正確的「url映射」標記。) – edwardmlyte

+0

您驗證了這個bean的名字是相同的名字,並且出現在根應用程序上下文中?你能發佈那個配置(沿着w /它的文件名)和你的整個web.xml嗎?您提到的文檔中的問題記錄爲https://jira.spring.io/browse/SEC-2466,應該從3.2.1.RELEASE中解決。請參閱http://docs.spring.io/spring-security /site/docs/3.2.x/reference/htmlsingle/#csrf-multipart –