Spring 3.0 MVC 中的多选

发布于 2024-10-05 17:57:42 字数 3644 浏览 3 评论 0原文

好吧,我已经尝试在 Spring MVC 中完成多重选择有一段时间了,但没有成功。

基本上我拥有的是一个技能类:

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

以及一个拥有多种技能的员工:

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

所有这些都映射到 Hibernate,但这不应该是一个问题。

现在我希望能够在 JSP 中从

我在 JSP 中尝试过这一点,但没有成功:

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

这是我的控制器:

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

但这似乎不起作用。我得到以下异常:

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

我觉得应该可以为模型提供一个表单,该模型可以从提供的选项列表中进行多项选择。在 Spring 3.0 MVC 中使用 form:selectform:options 的最佳实践是什么?

谢谢!

解决方案:

好的,以防万一有人想知道解决方案是什么。除了用户 01001111 修复之外:

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

我们需要向控制器添加一个 CustomCollectionEditor,如下所示:

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

这允许 Spring 在 JSP 和模型之间添加技能集。

Ok so I've been trying to accomplish multiple selects in Spring MVC for a while and have had no luck.

Basically what I have is a Skill class:

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

And an Employee who has multiple Skills:

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

All of these are mapped to Hibernate but that shouldn't be an issue.

Now I would like to be able to do in the JSP is to select Skills for an Employee from a <select multiple="true"> element.

I have tried this in the JSP with no luck:

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

Here is my Controller:

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

But this does not seem to work. I get the following Exception:

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

I feel like it should be possible where we can have a form for a Model that has multiple select from a list of options provided. What is the best practice to have form:select and form:options in Spring 3.0 MVC?

Thanks!

Solution:

Ok so just in case anyone wonders what the solution is. In addition to user 01001111 fix:

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

We need to add a CustomCollectionEditor to the controller as follows:

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

This allows Spring to add Sets of Skills between the JSP and Model.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

↘人皮目录ツ 2024-10-12 17:57:42

您需要将 items 属性视为变量,而不仅仅是引用变量名称:

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

放置 ${skillOptionList} 而不是 skillOptionList

You need to treat the items attribute as a variable, not just reference the variable name:

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

put ${skillOptionList} instead of skillOptionList

゛时过境迁 2024-10-12 17:57:42

您不需要自定义编辑器 - 这就是我所做的一切,它可以正确地来回复制值:

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

Project class:-
private Set<String> resources;

这就是我在控制器中添加数据的方式:

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

You don't need the custom editors - this is all I do and it copies the values back and forth correctly:

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

Project class:-
private Set<String> resources;

This is how I add the data in the controller:

Set<String> resources3 = new HashSet<String>();
resources3.add("XX");
萌能量女王 2024-10-12 17:57:42

我发现上述不起作用。
除了下面提到的内容之外,我还使用了以下答案: Spring select多个标签和绑定
(简单地说覆盖等于和哈希码)。我还根据上面的评论更改了 initBinder

它花了我很多时间来处理它,所以我想给任何看起来相同的东西并遇到我遇到的问题的人一个提示。

I found the above non working.
In addition to the things mentioned below i also used the answer in: Spring select multiple tag and binding
(simply put overide equals and hashcode). I have also changed initBinder based on the comment above

It took me a lot of time to cope with it so i thought to give a hint to anyone looking the same thing and having the problems i met with.

南笙 2024-10-12 17:57:42

tkeE2036:我想知道你说它对你有什么作用?每个选项的值是“name”,而不是“id”。但随后在 ConvertElement 方法中,您将接收到的元素(即名称)视为 id。我的猜测是,如果您尝试将每个选项的值设置为“id”,您将得到一个空字符串作为每个选项的值,因为您使用了错误的 PropertyEditor。

tkeE2036: I wonder how you said it worked for you at all? The value of each option is "name", not "id". But then in the convertElement method you treat the received element (which is a name), as if it were the id. My guess is that if you tried to set the value of each option as "id", you would get an empty string as the value of each option, because you are using the wrong PropertyEditor.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文