java 需要帮助使用 Spring MVC 表单绑定 Set
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5212408/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Need help with binding Set with Spring MVC form
提问by Javi
I have been trying for last 3 days still i am not able to solve my problem
过去 3 天我一直在尝试,但仍然无法解决我的问题
I have Person Class
我有个人类
@SuppressWarnings("rawtypes")
@OneToMany(cascade = CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="person")
@JoinColumn(name="person_id")
public Set<Book> books = new HashSet<Book>();
class Book
book_id
person_id
In my JSP form i have
在我的 JSP 表单中,我有
<c:forEach items="${BookList}" var="var1" varStatus="counter">
<input type="checkbox" name="books[${counter.index}].book_id" value="${var1.book_id}" >${var1.book_name}</input>
</c:forEach>
I am inserting the books in table depending upon the check boxes The book list is populated from refrenceData model.
我根据复选框在表格中插入书籍书籍列表是从 refrenceData 模型填充的。
COntroller
控制器
@RequestMapping(value = "/persons/add", method = RequestMethod.GET)
public String getAdd(Model model) {
logger.debug("Received request to show add page");
// Create new Person and add to model
// This is the formBackingOBject
model.addAttribute("personAttribute", new Person());
// This will resolve to /WEB-INF/jsp/addpage.jsp
return "hibernate/addpage";
}
@RequestMapping(value = "/persons/add", method = RequestMethod.POST)
public String add(@Valid @ModelAttribute("personAttribute") Person person, BindingResult result) {
logger.debug("Received request to add new person");
if (result.hasErrors())
return "hibernate/addpage";
else
personService.add(person);
// This will resolve to /WEB-INF/jsp/addedpage.jsp
return "hibernate/addedpage";
}
Now if i have single Book object then this works ok and data is entered in DB but if i have set then it says invalid property book[1]
现在,如果我有单个 Book 对象,那么这可以正常工作并且数据已输入到数据库中,但如果我已设置,则它会显示无效的属性书 [1]
After searching a lot on SO and Google i leart that i have two option
在 SO 和 Google 上搜索了很多之后,我了解到我有两个选择
PropertyEditor
AutoPopulatingList
I don't know how to use them in my case. Can anyone help me , where do i have to use them and how to use it
我不知道如何在我的情况下使用它们。任何人都可以帮助我,我必须在哪里使用它们以及如何使用它
回答by Javi
Look at this question Bind objects in a Set collection
看这个问题在 Set 集合中绑定对象
You need to use another type of Collection. I'd recommend to use a List instead of a Map. When you send from the form a parameter with a name like:
您需要使用另一种类型的 Collection。我建议使用列表而不是地图。当您从表单发送一个名称如下的参数时:
name="books[0].book_id"
SpringMVC will look in the property called books (which is a Set for you) and then it will try to get the first element by doing books.get(0). Set don't have a get because Set has not an order.
SpringMVC 将查看名为books 的属性(它是您的Set),然后它会尝试通过books.get(0) 获取第一个元素。Set 没有 get 因为 Set 没有订单。
For the implementation of the list you can use AutoPopulatingList. It is an implementation of a lazy List which will create an object if it doesn't exist. For example if you invoke books[0].id and you haven't added a book in the position 0 of the list it will throw a NullPointerException, but if you use AutoPopulatingList it will create a new Book and addd it in that position if that position is empty.
对于列表的实现,您可以使用 AutoPopulatingList。它是一个惰性列表的实现,如果它不存在,它将创建一个对象。例如,如果您调用 books[0].id 并且您还没有在列表的位置 0 添加一本书,它将抛出 NullPointerException,但如果您使用 AutoPopulatingList,它将创建一个新书并将其添加到该位置,如果那个位置是空的。
public List<Book> books = new AutoPopulatingList<Book>(new ElementFactory<Book>() {
@Override
public Book createElement(final int index) throws ElementInstantiationException {
//call the constructor as you need
return new Book();
}
});
if you you are going to instanciate it with the default constructor of Book (that is Book()), you can use a syntax like this one:
如果要使用 Book 的默认构造函数(即 Book())实例化它,则可以使用如下语法:
public List<Book> books = new AutoPopulatingList<Book>(Book.class);
回答by danny.lesnik
When I have such complicated form i honestly prefer to use JSON and submit it using AJAX.
当我有如此复杂的表单时,老实说我更喜欢使用 JSON 并使用 AJAX 提交它。
{"person":{"id":1,"books":[{"person_id":2,"book_id":3},{"person_id":2,"book_id":6},{"person_id":3,"book_id":4}]}
@RequestMapping(value = "/persons/add", method = RequestMethod.POST)
@ResponseBody
public String add(@RequestBody Person person){
//ad your business logic
}
Your code will be validate by de-serializer and you will be able to save it. You can reed more about that in this post:
您的代码将由反序列化程序验证,您将能够保存它。您可以在这篇文章中了解更多相关信息:
http://blog.springsource.com/2010/01/25/ajax-simplifications-in-spring-3-0/
http://blog.springsource.com/2010/01/25/ajax-simplifications-in-spring-3-0/
回答by Kunal Mazumdar
Binding of Set isn't possible with Spring MVC as Sets do not have indexes to work with. Although you can iterate through sets in JSP and show the results. The solutions might be -
Spring MVC 无法绑定 Set,因为 Set 没有可使用的索引。虽然您可以遍历 JSP 中的集合并显示结果。解决方案可能是——
- Use another type of collection like List.
- Wrap your Set in a POJO, use your Set for showing its containing values in JSP. Once you want to post the form containing your selection, add new property in your POJO which is String(or similar) and provide this property as your PATH in JSP tag, which will get the selection data from JSP. Then in backend code, fill your set with this value.
- 使用另一种类型的集合,如 List。
- 将您的 Set 包装在 POJO 中,使用您的 Set 在 JSP 中显示其包含的值。一旦您想要发布包含您的选择的表单,请在您的 POJO 中添加新的属性,它是字符串(或类似的),并在 JSP 标签中提供此属性作为您的 PATH,这将从 JSP 获取选择数据。然后在后端代码中,用这个值填充你的集合。
In case, your POJO is the also an Entity for your database creation using Hibernate, simply put @Transient on top of it. Hibernate will ignore this property while creating table.
如果您的 POJO 也是使用 Hibernate 创建数据库的实体,只需将 @Transient 放在它上面。Hibernate 在创建表时会忽略这个属性。