2014-04-22 12 views
5

Come si aggiunge la configurazione multipart a un'app di mvc di primavera che utilizza i controller con i metodi annotati con RequestMapping?MultipartConfig con Servlet 3.0 su Spring MVC

Background:

voglio abilitare la protezione CSRF e così ho aggiunto la sicurezza: CSRF tag nel mio config primavera. Ho una classe controller con un metodo annotato con RequestMapping usato per caricare file. Ho anche seguito lo caveat instructions in multiparte per cui ho aggiunto il filtro multipart sopra il filtro di sicurezza. Quando ho provato a caricare un file dopo aver aggiunto il tag csrf, ho ottenuto un'eccezione attorno a un metodo getParts() mancante. Un rapido google ha evidenziato che ciò era dovuto all'utilizzo di una versione di jetty basata sulle specifiche della servlet 2.5. Ho aggiornato il plugin jetty-maven a 8.1.14.v20131031 e ho provato a caricare di nuovo. Con conseguente:

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) 

Dove metto la configurazione più parti per la configurazione XML? Tutta la documentazione dice di aggiungere la multipart-config nel tag servlet per il servlet specifico in web.xml. Però c'è solo un singolo servlet per la mia applicazione. Quindi l'ho aggiunto a quello e continuo a ottenere lo stesso problema.

<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> 

ho anche aggiornato la posizione dello schema in alto web.xml per puntare alla versione 3.0 delle specifiche servlet, provenienti da http://www.mkyong.com/web-development/the-web-xml-deployment-descriptor-examples/.

Qualsiasi aiuto?

Edit: aggiunte le seguenti Riles per Rob:

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> 

risposta

9

Credo che si hanno problemi legati alla SPR-11373. Nello specifico, le specifiche della servlet non sono chiare su cosa dovrebbe accadere quando si esegue la risoluzione multipart in un filtro.

Hai provato a utilizzare commons-fileupload invece? Questa è probabilmente l'opzione migliore. In primo luogo aggiungere il seguente dipendenza:

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

Avanti assicurarsi di avere la seguente definizione di fagioli nel vostro contesto di applicazione principale.

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

Si può trovare un esempio di lavoro completo con entrambi i comuni-upload (preferisco questa soluzione) e l'utilizzo di Tomcat utilizzando allowCasualMultipartParsing su SEC-2471

+0

sto già usando quel importazione e fagioli definizione. – edwardmlyte

+0

Correzione, sto usando la classe che estende CommonsMultipartResolver. Ma ho provato direttamente con la sola CMR che ha provocato lo stesso errore. (Problema separato: la documentazione di avvertenza su csrf deve essere aggiornata in quanto indica di usare il tag "nome-servlet" all'interno della mappatura del filtro multipart ma nel tuo esempio vedo che usi il tag "url-mapping" corretto.) – edwardmlyte

+0

Hai verificato che il nome del bean è lo stesso nome e presente nel contesto dell'applicazione root? Puoi pubblicare quella configurazione (insieme al nome del file) e all'intero web.xml? Il problema nei documenti che hai menzionato è stato registrato come https://jira.spring.io/browse/SEC-2466 e dovrebbe essere risolto al 3.2.1.RELEASE Vedi http://docs.spring.io/spring-security /site/docs/3.2.x/reference/htmlsingle/#csrf-multipart –

Problemi correlati