2014-04-22 30 views
5

Jak dodać konfigurację wieloczęściową do wiosennej aplikacji mvc, która używa kontrolerów z metodami opisanymi w RequestMapping?MultipartConfig z serwletem 3.0 na wiosnę MVC

Tło:

Chcę włączyć ochronę CSRF a więc dodałem bezpieczeństwa: CSRF tag w moim wiosennym config. Mam klasę kontrolera z metodą opisaną za pomocą polecenia RequestMapping używanego do przesyłania plików. Podążałem także za wieloczęściową wersją caveat instructions, dzięki czemu dodałem filtr wieloczęściowy nad filtrem zabezpieczeń. Kiedy próbowałem załadować plik po dodaniu znacznika csrf, otrzymałem wyjątek dotyczący brakującej metody getParts(). Szybkie podkreślenie google było spowodowane użyciem wersji mola opartej na specyfikacji serwletu 2.5. Zaktualizowałem jetty-maven-plugin do wersji 8.1.14.v20131031 i spróbowałem ponownie przesłać. W wyniku tego:

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) 

Gdzie umieścić konfigurację wieloczęściową do konfiguracji xml? Cała dokumentacja mówi o dodaniu wieloczęściowej konfiguracji w tagu serwletu dla określonego serwletu w web.xml. Jest jednak tylko jeden serwlet dla mojej aplikacji. Więc dodałem to do tego i wciąż mam ten sam problem.

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

ja również zaktualizowane lokalizację schematu na szczycie web.xml wskazać w wersji 3.0 specyfikacji serwletów, pozyskiwane z http://www.mkyong.com/web-development/the-web-xml-deployment-descriptor-examples/.

Każda pomoc?

Edit: dodano następujące riles 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> 

Odpowiedz

9

wierzę masz problemy związane z SPR-11373. W szczególności specyfikacja serwletów nie jest jasna, co powinno się stać podczas wykonywania rozdzielczości wieloczęściowej w filtrze.

Czy próbowałeś zamiast tego używać ładowania plików wspólnych? To prawdopodobnie najlepsza opcja. Najpierw dodaj następującą zależność:

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

Następnie upewnij się, że posiadasz następującą definicję fasoli w kontekście aplikacji root.

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

można znaleźć kompletny pracy przykład z obu świetlicy przesłania (preferują takie rozwiązanie) i za pomocą Tomcat korzystając allowCasualMultipartParsing na SEC-2471

+0

już używam tej definicji importu i fasoli. – edwardmlyte

+0

Korekta, używam klasy, która rozszerza CommonsMultipartResolver. Ale wypróbowano tylko samą CMR, co spowodowało ten sam błąd. (Oddzielny problem: dokumentacja zastrzeżenia na temat csrf wymaga aktualizacji, ponieważ nakazuje używać znacznika "servlet-name" w odwzorowaniu filtru wieloczęściowego, ale w twoim przykładzie widzę, że używasz poprawnego tagu "url-mapping".) – edwardmlyte

+0

Sprawdziłeś to nazwa fasoli jest taka sama i obecna w kontekście aplikacji root? Czy możesz opublikować tę konfigurację (wraz z nazwą pliku) i cały plik web.xml? Problem w wymienionych dokumentach został zarejestrowany jako https://jira.spring.io/browse/SEC-2466 i powinien zostać naprawiony od wersji 3.2.1.RELEASE Patrz http://docs.spring.io/spring-security /site/docs/3.2.x/reference/htmlsingle/#csrf-multipart –