Announcement Announcement Module
Collapse
No announcement yet.
Cannot upload file using web flow Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Cannot upload file using web flow

    I am having trouble getting files to upload using Spring Web Flow. (My background: Java - advanced, Spring - intermediate, Web Flow - novice.) Whenever I put
    Code:
    enctype="multipart/form-data"
    into my form on my jsp, Web Flow isn't getting called. Here is my jsp:

    Code:
    <%@ include file="../includes/header.jsp" %>
    
    <%@ include file="includes/menu.jsp" %>
    
    <form name="uploadForm" action="memberPhotos.html" method="post" enctype="multipart/form-data">
    	<input type="hidden" name="_flowExecutionId" value="$&#123;flowExecutionId&#125;" />
    	<table>
    		<tbody>
    			<tr>
    				<td colspan="2">
    					<input type="hidden" name="isPrimary" value="$&#123;isPrimary&#125;" />
    					<input type="file" name="photoFile" width="75" />
    				</td>
    			</tr>
    			<tr>
    				<td>
    					<input type="submit" name="_eventId_cancel" value="Cancel" />
    				</td>
    				<td>
    					<input type="submit" name="_eventId_upload" value="Upload Photo" />
    				</td>
    			</tr>
    		</tbody>
    	</table>
    </form>
    
    <%@ include file="../includes/footer.jsp" %>
    Here are the pertinent parts of my flow.xml:

    Code:
    	<view-state id="upload.photo.view" view="member/member.Profile.photos.upload.view">
    		<entry>
    			<action bean="photos.formAction" method="setupForm" />
    		</entry>
    		<transition on="upload" to="uploadPhoto" />
    		<transition on="cancel" to="photos.view" />
    	</view-state>
    	
    	<action-state id="uploadPhoto">
    		<action bean="photos.upload.formAction" method="uploadPhoto"/>
    		<transition on="success" to="photos.view" />
    		<transition on="error" to="upload.photo.view" />
    	</action-state>
    As you can see, I am not using the binding method because I want to check attributes of the file (such as contentType) and binding afaik will only put the content into a byte array, which tells me nothing about the file other than its size and content.

    Here is my code for handling the upload:

    Code:
    public class UploadPhotoFormAction extends ServiceAwareWebFlowFormAction &#123;
    	public Event uploadPhoto&#40;RequestContext context&#41; throws Exception &#123;
    		System.err.println&#40;"uploading photo!"&#41;;
    		Object source = context.getLastEvent&#40;&#41;.getSource&#40;&#41;;
    		System.err.println&#40;"source = " + source&#41;;
    		if &#40;!&#40;source instanceof MultipartHttpServletRequest&#41;&#41; &#123;
    			System.err.println&#40;"returning error!"&#41;;
    			return error&#40;&#41;;
    		&#125;
    		User user = &#40;User&#41; getFormObject&#40;context&#41;;
    		System.err.println&#40;"user = " + user&#41;;
    		user = service.getUserByUsername&#40;user.getUsername&#40;&#41;&#41;;
    		Boolean isPrimary = Boolean.valueOf&#40;&#40;String&#41; context.getRequestScope&#40;&#41;.getRequiredAttribute&#40;"isPrimary"&#41;&#41;;
    		System.err.println&#40;"isPrimary = " + isPrimary&#41;;
    		MultipartHttpServletRequest request = &#40;MultipartHttpServletRequest&#41; source;
    		Iterator fileNames = request.getFileNames&#40;&#41;;
    		if &#40;fileNames.hasNext&#40;&#41;&#41; &#123;
    			String fileName = &#40;String&#41; fileNames.next&#40;&#41;;
    			System.err.println&#40;"fileName = " + fileName&#41;;
    			MultipartFile file = request.getFile&#40;fileName&#41;;
    			Photo photo = new Photo&#40;&#41;;
    			photo.setContent&#40;file.getBytes&#40;&#41;&#41;;
    			photo.setCroppedContent&#40;file.getBytes&#40;&#41;&#41;;
    			photo.setHeight&#40;0&#41;;
    			photo.setMimeType&#40;file.getContentType&#40;&#41;&#41;;
    			photo.setSize&#40;file.getSize&#40;&#41;&#41;;
    			photo.setUploadDate&#40;GregorianCalendar.getInstance&#40;&#41;&#41;;
    			photo.setWidth&#40;0&#41;;
    			photo.setPrimaryPhoto&#40;isPrimary&#41;;
    			user.getActiveProfile&#40;&#41;.addPhoto&#40;photo&#41;;
    		&#125;
    		getService&#40;&#41;.saveUser&#40;user&#41;;
    		return success&#40;&#41;;
    	&#125;
    
    &#125;
    Also, it's a given, but here's my CommonsMultipartResolver config and viewlistener config:

    Code:
    	<bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    		<property name="maxUploadSize"><value>1048576</value></property>
    	</bean>
    
    	<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    		<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
    		<property name="prefix"><value>/jsp/</value></property>
    		<property name="suffix"><value>.jsp</value></property>
    	</bean>
    I find that as long as I submit with the "enctype="multipart/form-data"" attribute in the form element, the page does NOT get handled by the Web Flow controller. I know this because the debugging "System.err.println"s never show up in the logs. Now, if I removed the "enctype="multipart/form-data"" attribute, the form submits and is handled by Web Flow, but of course it knows nothing about the file since the form is no longer a multipart form.

    So to conclude, having a "enctype" attribute in the form causes the Web Flow controller to be skipped. Removing "enctype" sends the post through Web Flow but does nothing with the file. Can anyone help?

  • #2
    Strange. I suggest you try to get the FileUpload sample application that comes with SWF PR5 up and running. That demonstrates a file upload scenario handled by SWF.

    Erwin

    Comment


    • #3
      Yes, I have the fileupload sample up and running, but again, it's binding the file to a byte array...which is not what I want to do. I'm trying to tinker with some of the eventIds and such to see if there's something causing a problem in there...

      Comment


      • #4
        Okay, so in the case of the FileUpload sample the multipart form (with enctype) is posting correctly to the SWF controller and being processed by SWF. Maybe you can put a breakpoint in the SpringMVC DispatcherServlet to figure out why it is not delegating to the SWF FlowController for your multipart HTML form.

        Erwin

        Comment


        • #5
          Wow, my first post on the forum and I have to go an make a newbie mistake. :oops: After a lot of debugging I finally realized the problem was in my multipartResolver bean registration.... I left out this:

          Code:
          id="multipartResolver"
          ugh...how stupid...

          Thanks for taking a look klr8. So far, I like web flow!

          Comment


          • #6
            Sorry but i can a question.
            How can getRealPath of image when browse file in case?

            Thank!

            Comment

            Working...
            X