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="${flowExecutionId}" />
<table>
<tbody>
<tr>
<td colspan="2">
<input type="hidden" name="isPrimary" value="${isPrimary}" />
<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 {
public Event uploadPhoto(RequestContext context) throws Exception {
System.err.println("uploading photo!");
Object source = context.getLastEvent().getSource();
System.err.println("source = " + source);
if (!(source instanceof MultipartHttpServletRequest)) {
System.err.println("returning error!");
return error();
}
User user = (User) getFormObject(context);
System.err.println("user = " + user);
user = service.getUserByUsername(user.getUsername());
Boolean isPrimary = Boolean.valueOf((String) context.getRequestScope().getRequiredAttribute("isPrimary"));
System.err.println("isPrimary = " + isPrimary);
MultipartHttpServletRequest request = (MultipartHttpServletRequest) source;
Iterator fileNames = request.getFileNames();
if (fileNames.hasNext()) {
String fileName = (String) fileNames.next();
System.err.println("fileName = " + fileName);
MultipartFile file = request.getFile(fileName);
Photo photo = new Photo();
photo.setContent(file.getBytes());
photo.setCroppedContent(file.getBytes());
photo.setHeight(0);
photo.setMimeType(file.getContentType());
photo.setSize(file.getSize());
photo.setUploadDate(GregorianCalendar.getInstance());
photo.setWidth(0);
photo.setPrimaryPhoto(isPrimary);
user.getActiveProfile().addPhoto(photo);
}
getService().saveUser(user);
return success();
}
}
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?