java Spring 表单命令可以是 Map 吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/736186/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can a Spring form command be a Map?
提问by Steve Kuo
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.
Spring 表单命令可以是 Map 吗?我通过扩展 HashMap 使我的命令成为 Map 并使用['property']符号引用属性,但它不起作用。
Command:
命令:
public class MyCommand extends HashMap<String, Object> {
}
HTML form:
HTML表格:
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?
这是不允许的还是我的语法不正确?
回答by cletus
Springn MVC commands need to use JavaBeans naming conventins (ie getXXX() and setXXX()) so no you can't use a map for that.
Springn MVC 命令需要使用 JavaBeans 命名约定(即 getXXX() 和 setXXX()),因此您不能为此使用映射。
One alternative is to have a bean with a single Map property ie:
一种替代方法是让 bean 具有单个 Map 属性,即:
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):
然后你可以做这样的事情(不是 100% 确定语法,但它是可能的):
Name: <form:input path="properties['name']" />
回答by Marius Jeskulke
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)
结合 cletus 和 dbell 的答案,我实际上可以使它工作,并希望与您分享解决方案(包括提交表单时的值绑定,cletus 解决方案报告的缺陷)
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.
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;
}
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.
我验证了 SettingsInformation bean 实际上填充了表单中的值。
Thanks for helping me with this one; If you have any questions feel free to ask.
谢谢你帮我解决这个问题;如果您有任何问题随时问。
回答by Deprecated Darren
Ok i have a solution that works for me i use MapUtils.lazyMap
好的,我有一个适合我的解决方案,我使用 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
//在我的JSP中
<input type="text" value="testthis" name="templateMap['keyName'].propertyValue"/>
回答by Deprecated Darren
Yes it can but... You need to reference it as <form:input path="name[index].key|value"/>
e.g.
是的,它可以,但是...您需要将其引用为<form:input path="name[index].key|value"/>
例如
<form:input path="name[0].value"/>
<form:input path="name[0].value"/>

