Spring Webflow — IllegalStateException при использовании multipart/form-data и загрузки файлов

Я пытаюсь добавить загрузку файла в обработку формы Spring Webflog. Поскольку enctype формы не установлен на multipart/form-data, отправка формы работает нормально. Но после того, как я добавил enctype="multipart/form-data" в свою форму Spring, возникает это исключение:

java.lang.IllegalStateException: A flow execution action URL can only be obtained in a RenderRequest or a ResourceRequest
    at org.springframework.webflow.context.portlet.PortletExternalContext.getFlowExecutionUrl(PortletExternalContext.java:215)
    at org.springframework.webflow.engine.impl.RequestControlContextImpl.getFlowExecutionUrl(RequestControlContextImpl.java:178)
    at org.springframework.webflow.mvc.view.AbstractMvcView.render(AbstractMvcView.java:189)
    at org.springframework.webflow.engine.ViewState.render(ViewState.java:293)
    at org.springframework.webflow.engine.ViewState.refresh(ViewState.java:242)
    at org.springframework.webflow.engine.ViewState.resume(ViewState.java:220)
    at org.springframework.webflow.engine.Flow.resume(Flow.java:537)
    at org.springframework.webflow.engine.impl.FlowExecutionImpl.resume(FlowExecutionImpl.java:259)
    at org.springframework.webflow.executor.FlowExecutorImpl.resumeExecution(FlowExecutorImpl.java:169)
    at org.springframework.webflow.mvc.portlet.FlowHandlerAdapter.handleAction(FlowHandlerAdapter.java:161)
    at org.springframework.web.portlet.DispatcherPortlet.doActionService(DispatcherPortlet.java:670)
    at org.springframework.web.portlet.FrameworkPortlet.processRequest(FrameworkPortlet.java:520)
    at org.springframework.web.portlet.FrameworkPortlet.processAction(FrameworkPortlet.java:461)
    at com.liferay.portlet.FilterChainImpl.doFilter(FilterChainImpl.java:71)

Я добавил CommonsMultipartResolver в свой весенний контекст:

<bean id="multipartResolver"
      class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
  <!-- Limit uploads to one byte smaller than the server is allowed to handle -->
  <property name="maxUploadSize" value="100000" />
</bean>

и иметь commons-fileupload.jar в моем pom.xml:

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

Мой JSP выглядит так:

<portlet:actionURL var="processFormAction" >
    <portlet:param name="execution" value="${flowExecutionKey}"/>
</portlet:actionURL>
<form:form action="${processFormAction}" modelAttribute="customerModel" enctype="multipart/form-data" method="post" >
    <form:input path="firstName" cssClass="input-size-1 valid-required" />
    <form:input path="lastName" cssClass="input-size-1  valid-required" />
    <input name="avatar" id="avatar" type="file"/>
    <input type="submit" name="_eventId_submit" id="send" value="Submit"/>
</form:form>

Мое определение flow.xml:

<view-state id="state1" model="customerModel">
    ...
    <transition on="submit" to="submitFormActions"/>
</view-state>

<action-state id="submitFormActions">
    <evaluate expression="portletAction.processForm(customerModel, flowRequestContext)" />
    <transition on="success" to="state2"/>
    <transition on="error" to="state1" />
</action-state>

Объект модели:

public class CustomerModel implements Serializable{
    private String firstName;
    private String lastName;
    private MutlipartFile avatar;

    ...
    //public getters and setters
}

Есть мысли, что может быть не так? Как я уже сказал, без enctype="multipart/form-data" обработка формы работает хорошо.

Спасибо


person shimon001    schedule 06.08.2014    source источник
comment
Вы проверили, входит ли он в метод portletAction.processForm с помощью отладки? Опубликуйте полную трассировку стека ошибки.   -  person Prasad    schedule 07.08.2014
comment
Привет @Prasad, спасибо за ваш ответ. Метод portletAction.processForm никогда не используется при использовании multipart/form-data в моей форме. Я проверил отладчиком. Полную трассировку стека можно увидеть здесь. Мне кажется, что фаза действия будет пропущена (отладчик переходит сразу в состояние представления state1 и пытается отобразить представление), но я не могу найти ошибку в файле конфигурации потока и, как я уже сказал, без multipart/ form-data enctype, обработка формы работает нормально (метод processForm вводится после отправки).   -  person shimon001    schedule 07.08.2014


Ответы (1)


Вы используете org.springframework.web.multipart.commons.CommonsMultipartResolver, который не знает о контексте портлета. Вам нужно изменить CommonsMultipartResolver на:

    <bean id="portletMultipartResolver"
        class="org.springframework.web.portlet.multipart.CommonsPortletMultipartResolver">
        <!-- one of the properties available; the maximum file size in bytes -->
        <property name="maxUploadSize" value="100000"/>
    </bean>

Кроме того, чтобы этот компонент распознавался DispatcherPortlet, вам необходимо определить идентификатор этого компонента, как указано выше. документ< /а> говорит:

    Any configured PortletMultipartResolver bean must have the following id (or name): "portletMultipartResolver". 
    If you have defined your PortletMultipartResolver with any other name, then the DispatcherPortlet will not 
    find your PortletMultipartResolver, and consequently no multipart support will be in effect.
person Prasad    schedule 07.08.2014
comment
Спасибо @Prasad, это решило мою проблему. Как я и предполагал - это была моя глупая ошибка :/ ... - person shimon001; 08.08.2014