SPRING-MVC: Как из формы получить коллекцию объектов?

 
 
 
Сообщения:133
Нужно ли писать свой CustomEditor?

есть класс Book, даю кусок кода:
@Entity
@Table(name = "BOOK")
public class Book implements Serializable{
    private Long id;
    //...
    private Collection<Author> authors;
    //...
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
    @JoinTable(name = "BOOK_AUTHOR",
            joinColumns = @JoinColumn(name = "ID_BOOK"),
            inverseJoinColumns = @JoinColumn(name = "ID_AUTHOR")
    )
    public Collection<Author> getAuthors() {
        return authors;
    }
//...
}

Часть кода класса Author:
@Entity
@Table(name="AUTHOR")
public class Author implements Serializable{
    private Long id;
    private String name;
    private String surname;
    private Collection<Book> books;
//...
@ManyToMany(mappedBy = "authors", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    public Collection<Book> getBooks() {
        return books;
    }
//...
}

моя форма создания книги:
<sf:form method="POST" modelAttribute="book" action="${pageContext.request.contextPath}/books" >
                <table>
                    //...часть кода отсутствует
                    <tr>
                        <th>Автор(ы)</th>
                        <td>
                            <sf:select path="authors" multiple="true" size="6">
                                <c:forEach items="${authors}" var="author">
                                    <sf:option value="${author.id}">${author.name} ${author.surname}</sf:option>
                                </c:forEach>
                            </sf:select>
                            <sf:errors path="authors" cssClass="error"/>
                        </td>
                    </tr>
                </table>
            <input type="submit" value="Добавить"/>
        </sf:form>

Т.к. у книги может быть несколько авторов, то у меня выпадающий список с множественным выбором. И в одной строчке располагается и имя, и фамилия.
Естественно, при отправке данных из формы получаем сообщение о том, что невозможно получить объект из строки:
Quote:

Failed to convert property value of type java.lang.String[] to required type java.util.Collection for property authors; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [com.springapp.mvc.domain.Author] for property authors[0]: no matching editors or conversion strategy found

Вот методы из моего контроллера
// перенаправление на страничку с формой
 @RequestMapping(method = RequestMethod.GET, params = "new")
    public String fillFormForCreatingBook(Model model){
        model.addAttribute("book",new Book());
        model.addAttribute("authors", authorService.findAll());
        return "books/create";
    }

// валидация и сохранение данных из формы
    @RequestMapping(method = RequestMethod.POST)
    public String createBookFromForm(@Valid Book book, BindingResult bindingResult){
        if (bindingResult.hasErrors()){
            return "books/create";
        }
        bookService.save(book);
        return "redirect:books/"+book.getId();
    }


Че то я туго соображаю, как это решается. Встречал примеры, что нужен метод с @InitBinder, дополнительный класс СustomEditor, но никак не соображу, как оно фунциклирует, чтоб применить к своей ситуации. Буду рад помощи.
Изменен:16 авг 2013 09:38
 
 
Сообщения:133
Как оказывается все просто!!! Блин, даже не верится, что так просто. Если честно, я не верил, что оно так будет работать. Но запустил и с первого раза все получилось. Вот решение.
Добавляю в свой контроллер вложенный класс и метод, аннотированный @InitBinder. Собственно по коду все ясно. По моему, очень удобная штука.
class AuthorEditor extends PropertyEditorSupport {

        @Override
        public void setAsText(String text){
            Long id = Long.parseLong(text);
            Author author = authorService.findById(id);
            setValue(author);
        }
    }

    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(Author.class, new AuthorEditor());
    }

Вопрос решен!
Изменен:16 авг 2013 10:28
 
Модераторы:Нет
Сейчас эту тему просматривают:Нет