commandClass setter methods are not invoked while implementing SimpleFormController in spring 3.x, Calling getter method on command odject returns null value.
uploadMessageBundle.jsp
<div class="instruction">
<spring:message code="messagebundle.upload.instruction"/>
</div>
<form method="post" action="uploadMessageBundle.htm" enctype="multipart/form-data">
<input type="file" name="file"/><br/>
<spring:bind path="command.locale">
<select name="${status.expression}">
<c:forEach var="locale" items="${locales}" varStatus="status">
<option value="${locale}">${locale}</option>
</c:forEach>
</select>
</spring:bind>
<br/>
<table>
<tr>
<td class="form_text"></td>
<td>
<input type="submit" name="_target1" class="active" value="<spring:message code='messagebundle.upload' />"/>
<input type="submit" name="_cancel" value="<spring:message code='messagebundle.cancle'/>"/>
</td>
</tr>
</table>
</form>
</div>
<jsp:directive.include file="/templates/footer.jsp"/>
UploadMessageBundleController.java
package org.sakaiproject.adminmessagebundle.tool;
import org.sakaiproject.messagebundle.api.MessageBundleService;
import org.sakaiproject.messagebundle.api.MessageBundleProperty;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.validation.BindException;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.multipart.support.ByteArrayMultipartFileEditor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.*;
public class UploadMessageBundleController extends AbstractUploadController {
MessageBundleService messageBundleService;
protected Map referenceData(HttpServletRequest request) throws Exception {
Map map = new HashMap();
map.put("locales",messageBundleService.getLocales());
return map;
}
protected void doSubmitAction(Object command) throws Exception {
try {
setCommandClass(FileUploadBean.class);
setCommandName("command");
setSuccessView("messageBundleHome");
setFormView("uploadMessageBundle");
FileUploadBean fileUploadBean = (FileUploadBean) command;
List properties = new ArrayList();
InputStream myxls = new ByteArrayInputStream(fileUploadBean.getFile());
HSSFWorkbook wb = new HSSFWorkbook(myxls);
HSSFSheet sheet = wb.getSheetAt(0); // first sheet
int rows = 0;
boolean foundHeaderRow = false;
for (Iterator i =sheet.rowIterator();i.hasNext();)
{
HSSFRow row = (HSSFRow) i.next();
if ("module".equals(row.getCell((short)0).getStringCellValue())) {
foundHeaderRow = true;
continue;
}
if (foundHeaderRow) {
MessageBundleProperty mbp = new MessageBundleProperty();
mbp.setModuleName(row.getCell((short)0).getStringCellValue());
mbp.setBaseName(row.getCell((short)1).getStringCellValue());
mbp.setPropertyName(row.getCell((short)2).getStringCellValue());
mbp.setValue(row.getCell((short)3).getStringCellValue());
mbp.setLocale(fileUploadBean.getLocale());
//TODO allow an optional 5 column for new translations
properties.add(mbp);
rows++;
}
}
if (foundHeaderRow == false) {
throw new Exception("Invalid excel file, can't find header row");
}
fileUploadBean.setRows(messageBundleService.importProperties(properties));
}catch(Exception e) {
e.printStackTrace();
}
}
protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response, Object command, BindException errors) throws Exception {
// when done, redirect to the main page and specify the "command" http parameter
ModelAndView modelAndView = null;
FileUploadBean fileUploadBean = (FileUploadBean) command;
if (isCancel(request)) {
modelAndView = new ModelAndView(getSuccessView(), "command", "list");
modelAndView.addObject("msg", "Upload Cancelled");
} else {
try {
doSubmitAction(command);
modelAndView = new ModelAndView(getSuccessView(), "command", "list");
modelAndView.addObject("msg", "Upload " + fileUploadBean.getRows() + " properties for locale " + fileUploadBean.getLocale());
} catch (Exception ex) {
modelAndView = new ModelAndView(getSuccessView(), "command", "list");
Map model = modelAndView.getModel();
model.put("error", ex.getMessage());
logger.warn("",ex);
}
}
return modelAndView;
}
protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder)
throws ServletException {
// to actually be able to convert Multipart instance to byte[]
// we have to register a custom editor
binder.registerCustomEditor(byte[].class, new ByteArrayMultipartFileEditor());
// now Spring knows how to handle multipart object and convert them
}
public void setMessageBundleService(MessageBundleService messageBundleService) {
this.messageBundleService = messageBundleService;
}
}
** bean configuration in xml file**
<bean id="uploadMessageBundleController" class="org.sakaiproject.adminmessagebundle.tool.UploadMessageBundleController">
<property name="messageBundleService"><ref bean="org.sakaiproject.messagebundle.api.MessageBundleService"/></property>
<property name="commandClass" value="org.sakaiproject.adminmessagebundle.tool.FileUploadBean"/>
<property name="commandName" value="command"/>
<property name="formView" value="uploadMessageBundle"/>
<property name="successView" value="redirect:messageBundleHome.htm"/>
</bean>
I have missed following bean definition in .xml file, so it was unable to call setter method in commandClass for file uploaded in the form.
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />