Spring 3.0 MVC 中的多选
好吧,我已经尝试在 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:select
和 form: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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您需要将 items 属性视为变量,而不仅仅是引用变量名称:
放置
${skillOptionList}
而不是skillOptionList
You need to treat the items attribute as a variable, not just reference the variable name:
put
${skillOptionList}
instead ofskillOptionList
您不需要自定义编辑器 - 这就是我所做的一切,它可以正确地来回复制值:
这就是我在控制器中添加数据的方式:
You don't need the custom editors - this is all I do and it copies the values back and forth correctly:
This is how I add the data in the controller:
我发现上述不起作用。
除了下面提到的内容之外,我还使用了以下答案: 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.
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.