2009-04-09 4 views
9

Une commande de forme de ressort peut-elle être une carte? J'ai fait ma commande une carte en étendant HashMap et référencé les propriétés en utilisant la notation ['property'] mais cela n'a pas fonctionné.Une commande de forme de ressort peut-elle être une carte?

Commande:

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

formulaire HTML:

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

Résultats dans l'erreur:

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? 

est-ce pas permis ou dois-je une syntaxe incorrecte?

Répondre

11

Les commandes MVC de Springn doivent utiliser des conventins nommant JavaBeans (ie getXXX() et setXXX()) donc vous ne pouvez pas utiliser de carte pour cela.

Une alternative est d'avoir un haricot avec une seule carte Propriété à savoir:

public class MyCommand { 
    private final Map<String, Object> properties = new HashMap<String, Object>(); 

    public Map<String, Object> getProperties() { return properties; } 
    // setter optional 
} 

Ensuite, vous pouvez faire quelque chose comme ça (pas sûr à 100% sur la syntaxe, mais il est possible):

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

Votre sintaxis est correct, mais les propriétés de la carte ne sont pas réellement liées. Le problème est que le code généré est quelque chose comme . Ainsi, lorsque vous soumettez ce formulaire, rien ne met la valeur correcte dans les propriétés. – sinuhepop

+0

Les valeurs de chaîne de carte peuvent être liées dans JSP. Les valeurs entières de la carte/de l'objet peuvent-elles être liées? –

+0

On dirait que la syntaxe fonctionne maintenant pour les cartes, au moins au printemps 3.0.7 – altumano

-1

Oui, il peut mais ... Vous devez le référencer comme <form:input path="name[index].key|value"/> par exemple

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

+0

A quoi sert le 0 ou l'index? –

1

Ok j'ai une solution qui fonctionne pour moi j'utilise MapUtils.lazyMap

// Mon domaine racine

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

    } 

// mon second domaine

public class AnotherDomainObj { 

    String propertyValue=""; 

     public String getPropertyValue() { 
      return propertyValue; 
     } 

     public void setPropertyValue(String propertyValue) { 
      this.propertyValue = propertyValue; 
    } 



} 

// Dans mon JSP

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

Les valeurs de chaîne de carte peuvent être liées dans JSP. Les valeurs entières de la carte/de l'objet peuvent-elles être liées? –

3

En combinant la réponse de Cletus et dbell je pouvais le faire fonctionner et que vous souhaitez partager la solution avec vous (y compris la liaison des valeurs lors de la présentation du formulaire, un défaut signalé pour la solution de Cletus)

Vous ne pouvez pas utiliser directement une carte comme commande, ont cependant un autre objet de domaine qui a besoin d'envelopper une carte paresseuse

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 est une classe qui enveloppe réellement la valeur.

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

La méthode du contrôleur fournissant le modèle ressemble à ceci:

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

Votre formulaire devrait ressembler à ceci

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

La soumission du formulaire de traitement de la méthode de commande fonctionne comme d'habitude

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

J'ai vérifié que le bean SettingsInformation est réellement rempli avec les valeurs du formulaire.

Merci de m'avoir aidé avec celui-ci; Si vous avez des questions, n'hésitez pas à les poser.

+0

Les valeurs de chaîne de carte peuvent être liées dans JSP. Les valeurs entières de la carte/de l'objet peuvent-elles être liées? –

Questions connexes