Comment passer @RequestParam et @ModelAttribute sous une forme

j'aimerais mélanger @RequestParam et @ModelAttribute en une seule forme de ressort et de contrôleur.

les choses que je fais dans mon contrôleur sont les suivantes:

@RequestMapping("/user/edit/{userId}")
public ModelAndView editUser(@PathVariable String userId, 
    @ModelAttribute User user, BindingResult bindingResult,
    @RequestParam Set<String> groups) {

    if(bindingResults.hasErrors() {
        //return back to form and correct errors
    } else {
        //save data and get out of form 
    }
} 

il y a simple user bean (id, firstName, lastName, etc) mais sans la propriété" groups". Il y a aussi simple groupe bean (id, nom, description) MAIS SANS aucune connexion avec L'utilisateur. Ainsi, au niveau logique, L'Utilisateur et le groupe sont totalement séparés.

In mon formulaire, lors de l'édition de User, il y a un élément html SELECT qui contient les ID de tous les groupes. Vous pouvez sélectionner plusieurs ids avec le remplissage des données de L'Utilisateur et l'envoyer au contrôleur.

Jusqu'à maintenant, tout fonctionne assez bien. Je obtiens utilisateur @ ModelAttibute correctement rempli. J'obtiens aussi des groupes de Set[String] de @RequestParam remplis avec des ids (Strings) sélectionnés.

Maintenant, je voudrais faire quelque chose de plus. Je dois écrire quelque chose qui au lieu de @RequestParam Les groupes Set [String] me donneront les groupes Set[Group] @RequestParam. Bien sûr, je peux le convertir directement dans ma méthode de controller editUser (...), mais ce n'est pas une solution sympa. J'ai donc décidé d'écrire une méthode custom @InitBinder qui le fera pour moi gentiment et en douceur.

et là le problème vient.

j'ai écrit l'initBinder comme suit:

[...]
webDataBinder.registerCustomEditor(Set.class, "groups", new CustomCollectionEditor(Set.class) {
    @Override
    protected Object convertElement(Object element) {
        if (element instanceof GroupName) {
            return element;
        }

        if (element instanceof String) {
            Group group = userCatalog.loadGroup((String) element);
            return group.getGroupName();
        }

        return null;
    }
});
[...]

Le problème est qu'il n'y a absolument aucun moyen d'appeler cette méthode. J'ai mis dans ce système de "débogage".hors.println(...) mais il n'a pas d'imprimer quoi que ce soit.

ma question est: comment écrire un InitBinder correct qui sera invoqué en réponse au tableau de chaînes de l'élément d'OPTION html et le convertir à mon ensemble d'utilisateurs.

j'ai changé quelques crochets [ et ] parce qu'il n'était pas affiché.

Merci pour votre aide.


pendant ce temps je suis tombé sur ce sujet: les éditeurs de propriétés personnalisés ne fonctionnent pas pour les paramètres de requête dans MVC de printemps?

et je pense que c'est la clé de la solution. En fait, comme le dit javadocs, l'argument" field " n'est nécessaire que lorsque L'on utilise ModelAttibute (ou form backing object qui est le même...), mais pas pour RequestParam. Est-ce qu'il y a une solution pour utiliser InitBinder avec RequestParam? Ou je dois écrire une méthode directe dans controller qui convertit les ids en Ensemble de groupe les objets?

3
demandé sur Community 2012-06-30 00:21:48

1 réponses

essayez d'enregistrer votre éditeur personnalisé juste contre le jeu.type de classe et en laissant le nom du champ pour voir si cela fonctionne.

webDataBinder.registerCustomEditor(Set.class, new CustomCol...

je soupçonne que le paramètre de champ indique le nom de la propriété D'un ModelAttribute et non le nom du paramètre request.

alternativement, vous pouvez utiliser un modèle de vue wrapper et utiliser un second ModelAttribute paramètre,

class GroupsViewModel {
    private List<Group> groups
    ...
}
0
répondu Rob Beardow 2012-07-01 11:15:58