Как опубликовать коллекцию полей формы в контроллере Spring?

#java #spring #spring-mvc

#java #spring #spring-mvc

Вопрос:

Предположим, у меня есть форма, подобная этой:

 <form method="post" action="/create">

    <input type="text" name="title.0" value="Curious George" />
    <input type="text" name="author.0" value="H.A. Rey" />
    <input type="text" name="date.0" value="2/23/1973" />

    <input type="text" name="title.1" value="Code Complete" />
    <input type="text" name="author.1" value="Steve McConnell" />
    <input type="text" name="date.1" value="6/9/2004" />

    <input type="text" name="title.2" value="The Two Towers" />
    <input type="text" name="author.2" value="JRR Tolkien" />
    <input type="text" name="date.2" value="6/1/2005" />

    <input type="submit" />
</form>
  

Как мне проанализировать это с контроллера Spring MVC 3.0?

Ответ №1:

name Атрибут не обязательно должен быть уникальным. Итак:

 <input type="text" name="title" value="Curious George" />
<input type="text" name="title" value="Code Complete" />
<input type="text" name="title" value="The Two Towers" />
  

И затем

 @RequestMapping("/create")
public void create(
    @RequestParam("title") List<String> titles, 
    @RequestParam("author") List<String> authors, ..) {..}
  

Порядок элементов должен быть сохранен в соответствии со спецификацией:

Имена / значения элементов управления перечислены в том порядке, в котором они отображаются в документе. Имя отделяется от значения символом ‘=’, а пары имя / значение отделяются друг от друга символом ‘amp;’.

Ответ №2:

Если вы можете изменить представление, в идеале вы должны сделать это с помощью какого-то списка.

Что-то вроде:

 <input type="text" name="books[0].title" value="Curious George" />
<input type="text" name="books[0].author" value="H.A. Rey" />
<input type="text" name="books[0].date" value="2/23/1973" />
  

у вас был бы класс Book, содержащий ваши 3 элемента.
и содержащий класс, который содержит список книг BookContainer

 public class BookContainer {
  private List <Book> books = new ArrayList<Book>();

  public List<Book> getBooks() {
    return books;
  }

  public void setBooks(List<Book> books) {
    this.books = books;
  }
}
  

Теперь в вашем контроллере у вас должен быть @ModelAttribute метод, который возвращает содержащий класс для привязки к:

 @ModelAttribute("container")
public BookContainer getBookContainer() {
  return new BookContainer;
}
  

наконец, у вас будет параметр @ModelAttribute для вашего метода сопоставления запросов:

 @RequestMapping
public void handlePost(@ModelAttribute("container") BookContainer container) {

}
  

spring автоматически добавит в ваш список столько книг, сколько вам нужно.

Комментарии:

1. Сегодня я довольно долго пытался воплотить эту идею в жизнь, но безуспешно. Я даже удалил большую часть своего кода и вставил ваш без каких-либо ограничений. Есть какие-либо предложения или указатели на то, как заставить это действительно работать?

2. Какую версию spring MVC вы используете? Я вспоминаю, что в 3.0.0 была ошибка, из-за которой [] не работал. В настоящее время я использую 3.0.5 — я также проведу небольшой тест чуть позже, чтобы убедиться, что я ничего не пропустил.

3. Я обновил свой ответ, основная причина, по которой это не сработало, заключалась в том, что, похоже, вы не можете напрямую привязываться к списку, но это работает нормально, если ваш список содержится в другом классе.

4. Спасибо, кирон. Я тоже на версии 3.0.5. Я посмотрю на это сегодня вечером и посмотрю, смогу ли я заставить это работать. Это было бы здорово, поскольку это чище, чем мой ответ о простом получении WebRequest.

5. Наконец, теперь вашим атрибутом ModelAttribute является «контейнер», но в вашем requestmapping вы все еще ссылаетесь на «книги», это то, что вы имели в виду? Кроме того, нужно ли будет изменить имена элементов inputs на container.books[0].title и т.д. Или нет?

Ответ №3:

Может ли ваш контроллер запросить сопоставление, просто взяв spring WebRequest в качестве параметра, а затем сделать что-то вроде:

 Map<String, String[]> params = request.getParameterMap();
int i = 0;
while ( true ) {
    String title = params.get( "title"   .i );
    if ( title != null ) {
        // get the rest and create your Book object or whatever
        i  = 1;
    }
    else {
        break;
    }
}