Can a Spring form command be a Map?

Can a Spring form command be a Map?

Can a Spring form command be a Map? I made my command a Map by extending HashMap and referenced the properties using the ['property'] notation but it didn't work.


public class MyCommand extends HashMap<String, Object> { } 

HTML form:

Name: <form:input path="['name']" /> 

Results in the error:

org.springframework.beans.NotReadablePropertyException: Invalid property '[name]' of bean class []: Bean property '[name]' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter? 

Is this not allowed or do I have incorrect syntax?

Using Spring to inject EasyMock mocks causes ClassCastException


BeanPropertySqlParameterSource and Doubles
Springn MVC commands need to use JavaBeans naming conventins (ie getXXX() and setXXX()) so no you can't use a map for that..
Conditionally Render In JSP By User
One alternative is to have a bean with a single Map property ie:.
jersey integration with spring
public class MyCommand {   private final Map<String, Object> properties = new HashMap<String, Object>();    public Map<String, Object> getProperties() { return properties; }   // setter optional } 
Then you can do something like this (not 100% sure on the syntax but it is possible):.
How can I use Spring XML configuration to set a bean property with list of all beans of a certain type?
Name: <form:input path="properties['name']" /> 

Need Spring version# - only have spring.jar file

Spring JMS Message Listener Container


How to have a class use applicationContext beans?
Combining the answer of cletus and dbell I could actually make it work and would like to share the solution with you (including binding of values when submitting the form, a flaw reported for cletus solution). You cannot use directly a map as command, however have another domain object that needs to wrap a lazy map.
public class SettingsInformation {      private Map<String, SettingsValue> settingsMap= MapUtils.lazyMap(new HashMap<String, SettingsValue>(),FactoryUtils.instantiateFactory(SettingsValue.class));      public Map<String, SettingsValue> getSettingsMap() {         return settingsMap;     }      public void setSettingsMap(Map<String, SettingsValue > settingsMap) {         this.settingsMap = settingsMap;     }  } 
SettingsValue is a class that actually wraps the value..
public class SettingsValue {  private String value;  public SettingsValue(String value) {     this.value = value; }   public SettingsValue() {  }  public String getValue() {      return value; }  public void setValue(String propertyValue) {      this.value = propertyValue; } 
The controller method providing the model looks like this:.
    @RequestMapping(value="/settings", method=RequestMethod.GET) public ModelAndView showSettings() {      ModelAndView modelAndView = new ModelAndView("settings");      SettingsDTO settingsDTO = settingsService.getSettings();     Map<String, String> settings = settingsDTO.getSettings();      SettingsInformation settingsInformation = new SettingsInformation();      for (Entry<String, String> settingsEntry : settings.entrySet()) {         SettingsValue settingsValue = new SettingsValue(settingsEntry.getValue());         settingsInformation.getSettingsMap().put(settingsEntry.getKey(), settingsValue);     }      modelAndView.addObject("settings", settingsInformation);      return modelAndView; } 
Your form should look like this.
<form:form action="${actionUrl}" commandName="settings">         <form:input path="settingsMap['exampleKey'].value"/>         <input type="submit" value="<fmt:message key=""/>"/> </form:form> 
The controller method handling form submission works as usual.
@RequestMapping(value="/settings", method=RequestMethod.POST) public ModelAndView updateSettings(@ModelAttribute(value="settings") SettingsInformation settings) { [...] } 
I verified the SettingsInformation bean is actually filled with the values in the form.. Thanks for helping me with this one; If you have any questions feel free to ask..


Ok i have a solution that works for me i use MapUtils.lazyMap. //My Root domain.
    public class StandardDomain {          private Map<String, AnotherDomainObj> templateMap= MapUtils.lazyMap(new HashMap<String, AnotherDomainObj>(),FactoryUtils.instantiateFactory(AnotherDomainObj.class));          public Map<String, AnotherDomainObj> getTemplateContentMap() {             return templateMap;         }          public void setTemplateContentMap(Map<String, AnotherDomainObj > templateMap) {             templateMap = templateMap;         }      } 
//my second domain.
public class AnotherDomainObj  {      String propertyValue="";          public String getPropertyValue() {            return propertyValue;         }          public void setPropertyValue(String propertyValue) {            this.propertyValue = propertyValue;      }    } 
//In my JSP.
<input type="text" value="testthis" name="templateMap['keyName'].propertyValue"/> 


Yes it can but...

You need to reference it as <form:input path="name[index].key|value"/> e.g.

. <form:input path="name[0].value"/> .

82 out of 100 based on 82 user ratings 982 reviews