【问题标题】:Can a Spring form command be a Map?Spring 表单命令可以是 Map 吗?
【发布时间】:2009-04-09 23:02:22
【问题描述】:

Spring 表单命令可以是 Map 吗?我通过扩展 HashMap 使我的命令成为 Map 并使用 ['property'] 表示法引用属性,但它不起作用。

命令:

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

HTML 表单:

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

导致错误:

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?

这是不允许的还是我的语法不正确?

【问题讨论】:

    标签: java spring spring-mvc


    【解决方案1】:

    Springn MVC 命令需要使用 JavaBeans 命名约定(即 getXXX() 和 setXXX()),所以不,您不能为此使用映射。

    另一种方法是让 bean 具有单个 Map 属性,即:

    public class MyCommand {
      private final Map<String, Object> properties = new HashMap<String, Object>();
    
      public Map<String, Object> getProperties() { return properties; }
      // setter optional
    }
    

    然后你可以做这样的事情(不是 100% 确定语法,但它是可能的):

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

    【讨论】:

    • 您的 sintaxis 是正确的,但地图属性并没有真正绑定。问题是生成的代码类似于 。因此,当您提交此表单时,不会在属性中放置正确的值。
    • 映射字符串值可以在 JSP 中绑定。 map/object的整数值可以绑定吗?
    • 看起来语法 现在适用于地图,至少在 Spring 3.0.7 中
    【解决方案2】:

    结合 cletus 和 dbell 的答案,我实际上可以让它工作,并希望与您分享解决方案(包括提交表单时的值绑定,cletus 解决方案报告的一个缺陷)

    您不能直接使用映射作为命令,但是有另一个需要包装惰性映射的域对象

    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 是一个实际包装值的类。

    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;
    }
    

    提供模型的控制器方法如下所示:

        @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;
    }
    

    您的表单应如下所示

    <form:form action="${actionUrl}" commandName="settings">
            <form:input path="settingsMap['exampleKey'].value"/>
            <input type="submit" value="<fmt:message key="settings.save"/>"/>
    </form:form>
    

    处理表单提交的控制器方法照常工作

    @RequestMapping(value="/settings", method=RequestMethod.POST)
    public ModelAndView updateSettings(@ModelAttribute(value="settings") SettingsInformation settings) {
    [...]
    }
    

    我验证了 SettingsInformation bean 实际上填充了表单中的值。

    感谢您帮我解决这个问题;如果您有任何问题,请随时提出。

    【讨论】:

    • 映射字符串值可以在 JSP 中绑定。 map/object的整数值可以绑定吗?
    【解决方案3】:

    好的,我有一个适合我的解决方案,我使用 MapUtils.lazyMap

    //我的根域

        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;
            }
    
        }
    

    //我的第二个域

    public class AnotherDomainObj  {
    
        String propertyValue="";
    
            public String getPropertyValue() {
               return propertyValue;
            }
    
            public void setPropertyValue(String propertyValue) {
               this.propertyValue = propertyValue;
         }
    
    
    
    }
    

    //在我的JSP中

    <input type="text" value="testthis" name="templateMap['keyName'].propertyValue"/>
    

    【讨论】:

    • 映射字符串值可以在 JSP 中绑定。 map/object的整数值可以绑定吗?
    【解决方案4】:

    可以,但是...您需要将其引用为<form:input path="name[index].key|value"/> 例如

    &lt;form:input path="name[0].value"/&gt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-18
      • 1970-01-01
      • 2019-06-21
      相关资源
      最近更新 更多