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.

Command:

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 [com.me.MyCommand]: 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

1:



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

2:



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="settings.save"/>"/> </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..


3:


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"/> 


4:


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