web-dev-qa-db-fra.com

Sélection multiple dans Spring 3.0 MVC

Ok donc j'ai essayé d'accomplir plusieurs sélections dans Spring MVC pendant un certain temps et je n'ai pas eu de chance.

Fondamentalement, ce que j'ai est une classe de compétence:

public class Skill {
    private Long id;
    private String name;
    private String description;
    //Getters and Setters
}

Et un employé qui a plusieurs compétences:

public class Employee {
    private Long id;
    private String firstname;
    private String lastname;
    private Set<Skill> skills;
    //Getters and Setters
}

Tous ces éléments sont mappés sur Hibernate mais cela ne devrait pas être un problème.

Maintenant, je voudrais pouvoir faire dans le JSP est de sélectionner les compétences pour un employé à partir d'un <select multiple="true"> élément.

J'ai essayé cela dans la JSP sans succès:

<form:select multiple="true" path="skills">
    <form:options items="skillOptionList" itemValue="name" itemLabel="name"/>
<form:select>

Voici mon contrôleur:

@Controller
@SessionAttributes
public class EmployeeController {
     @Autowired
     private EmployeeService service;

     @RequestMapping(value="/addEmployee", method = RequestMethod.POST)
     public String addSkill(@ModelAttribute("employee") Employee emp, BindingResult result, Map<String, Object> map) {

        employeeService.addEmployee(emp);

        return "redirect:/indexEmployee.html";
    }

    @RequestMapping("/indexEmployee")
    public String listEmployees(@RequestParam(required=false) Integer id, Map<String, Object> map) {

        Employee emp = (id == null ? new Employee() : employeeService.loadById(id));

        map.put("employee", emp);
        map.put("employeeList", employeeService.listEmployees());
        map.put("skillOptionList", skillService.listSkills());

        return "emp";
    }
}

Mais cela ne semble pas fonctionner. J'obtiens l'exception suivante:

SEVERE: Servlet.service() for servlet jsp threw exception
javax.servlet.jsp.JspException: Type [Java.lang.String] is not valid for option items

Je pense qu'il devrait être possible où nous pouvons avoir un formulaire pour un modèle qui a plusieurs sélections dans une liste d'options fournies. Quelle est la meilleure pratique pour avoir form:select et form:options dans Spring 3.0 MVC?

Merci!

Solution:

Ok donc juste au cas où quelqu'un se demanderait quelle est la solution. En plus du correctif utilisateur 01001111:

<form:select multiple="true" path="skills">
    <form:options items="${skillOptionList}" itemValue="name" itemLabel="name"/>
<form:select>

Nous devons ajouter un CustomCollectionEditor au contrôleur comme suit:

@Controller
@SessionAttributes
public class EmployeeController {

    @Autowired
    private EmployeeeService employeeService;

    @Autowired
    private SkillService skillService;

    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(Set.class, "skills", new CustomCollectionEditor(Set.class)
          {
            @Override
            protected Object convertElement(Object element)
            {
                Long id = null;

                if(element instanceof String && !((String)element).equals("")){
                    //From the JSP 'element' will be a String
                    try{
                        id = Long.parseLong((String) element);
                    }
                    catch (NumberFormatException e) {
                        System.out.println("Element was " + ((String) element));
                        e.printStackTrace();
                    }
                }
                else if(element instanceof Long) {
                    //From the database 'element' will be a Long
                    id = (Long) element;
                }

                return id != null ? employeeService.loadSkillById(id) : null;
            }
          });
    }
}

Cela permet à Spring d'ajouter des ensembles de compétences entre le JSP et le modèle.

26
Ian Dallas

Vous devez traiter l'attribut items comme une variable, pas seulement référencer le nom de la variable:

<form:select multiple="true" path="skills">
    <form:options items="${skillOptionList}" itemValue="name" itemLabel="name"/>
</form:select>

mettre ${skillOptionList} au lieu de skillOptionList

16
01001111

Vous n'avez pas besoin des éditeurs personnalisés - c'est tout ce que je fais et il copie correctement les valeurs d'avant en arrière:

<form:select path="project.resources">
    <form:option value="XX"/>
    <form:option value="YY"/>
</form:select>

Project class:-
private Set<String> resources;

Voici comment j'ajoute les données dans le contrôleur:

Set<String> resources3 = new HashSet<String>();
resources3.add("XX");
1
Vik

J'ai trouvé que ce qui précède ne fonctionnait pas. En plus des choses mentionnées ci-dessous, j'ai également utilisé la réponse dans: Spring select multiple tag and binding (mettez simplement overide equals et hashcode). J'ai également changé initBinder sur la base du commentaire ci-dessus

Il m'a fallu beaucoup de temps pour y faire face, alors j'ai pensé donner un indice à tous ceux qui regardent la même chose et qui ont les problèmes que j'ai rencontrés.

1
Alexandros

tkeE2036: Je me demande comment vous avez dit que cela fonctionnait pour vous? La valeur de chaque option est "nom", pas "id". Mais ensuite, dans la méthode convertElement, vous traitez l'élément reçu (qui est un nom), comme s'il s'agissait de l'id. Je suppose que si vous essayez de définir la valeur de chaque option comme "id", vous obtiendrez une chaîne vide comme valeur de chaque option, car vous utilisez le mauvais PropertyEditor.

0
rapt