Может ли команда формы Spring быть картой? - PullRequest
9 голосов
/ 10 апреля 2009

Может ли команда формы Spring быть картой? Я сделал свою команду Map, расширив HashMap и ссылаясь на свойства, используя нотацию ['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?

Это не разрешено или у меня неверный синтаксис?

Ответы [ 4 ]

11 голосов
/ 10 апреля 2009

Команды Springn MVC должны использовать условные обозначения имен JavaBeans (например, getXXX () и setXXX ()), поэтому вы не можете использовать карту для этого.

Одной из альтернатив является создание компонента с одним свойством 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']" />
3 голосов
/ 18 июля 2011

Объединив ответ Клетуса и Дебелла, я действительно мог бы заставить его работать и хотел бы поделиться с вами решением (включая привязку значений при отправке формы, недостаток, сообщенный для решения Клетус)

Вы не можете использовать карту непосредственно как команду, однако есть другой объект домена, который должен обернуть ленивую карту

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 фактически заполнен значениями в форме.

Спасибо, что помогли мне с этим; Если у вас есть какие-либо вопросы, не стесняйтесь спрашивать.

1 голос
/ 07 марта 2011

Хорошо, у меня есть решение, которое работает для меня, я использую 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"/>
0 голосов
/ 10 апреля 2009

Да, может, но ... Вы должны ссылаться на него как <form:input path="name[index].key|value"/> например

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...