2013-02-12 4 views
1

Почему сервер не видит список заполненных флажков?Spring MVC: список флажков, не возвращенных контроллеру на POST

Этот вопрос, кажется, здесь задан много раз, но детали для каждого реквестера настолько различны, что каждый раз, кажется, нужен другой ответ. Вот моя история.

Это мои классы, несущие данные. Предложение содержит список объектов Filter в атрибуте фильтра :.

public class Offer implements Serializable { 

    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    @Column(name="id") 
    private Long id = null; 

    @Column(name="title") 
    private String title = null; 
    [snip] 

    @ManyToMany(fetch=FetchType.EAGER) 
    @JoinTable(name = "offer_filter", 
     joinColumns = { @JoinColumn(name = "offer_id", nullable = false, updatable = false) }, 
     inverseJoinColumns = { @JoinColumn(name = "filter_id", nullable = false, updatable = false) }) 
    private List<Filter> filters; 

    [snip] 
} 

public class Filter implements Serializable { 

    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    @Column(name="id") 
    private Long id; 

    @NotBlank 
    @Length(max=100) 
    @Column(name="text") 
    private String text; 

    [snip] 

    @Transient 
    private boolean owned = false; 

    [snip] 
} 

Простой контроллер отправляет страницу offerEdit.jsp с полностью заполненным объектом Предложения. Объект содержит список фильтров. Из-за принадлежащего атрибута предварительно проверяется только один из трех фильтров. Это моделирует мой возможный план, в котором список фильтров - это весь юниверс и то, что принадлежит Приложению, является подмножеством.

Обратите внимание на примечания о том, что предложение имеет список фильтров, идущих на веб-страницу, но не видит, что он возвращается.

public class OfferController { 
    [snip] 

    @RequestMapping(value = "/edit", method = RequestMethod.GET) 
    public String getEdit(@RequestParam("id") Long id, Model model, HttpSession session) { 
     Offer offerAttribute = offerService.get(id); 

     // At this point, offerAttribute.filters has three elements. 
     // Mockup -- tells web page that only the middle one of the three Filters should be checked. 
     List<Filter> filters = offer.getFilters(); 
     Filter filter = filters.get(1); 
     filter.setOwned(true); 

     model.addAttribute("offerAttribute", offerAttribute); 

     return "offer/offerEdit"; 
    } 

    @RequestMapping(value = "/edit", method = RequestMethod.POST) 
    public String postEdit(@RequestParam("id") Long id, @Valid @ModelAttribute("offerAttribute") Offer offerAttribute, BindingResult result, HttpSession session, Model model) { 

     // At this point, offerAttribute.filters is null. 
     if(result.hasErrors()) { 
      result.reject("offer.invalidFields"); 

      return "offer/offerEdit"; 
     } 

     offerAttribute.setId(id); 
     offerService.edit(offerAttribute); 

     return "redirect:/offer/list"; 
    } 

    [snip] 
} 

Веб-страница имеет это для своей секции флажка. Я использую форму: флажок над формой: флажков, потому что я хочу использовать таблицу,

[snip] 
<form:form modelAttribute="offerAttribute" method="POST" action="${saveUrl}"> 
    <table> 
     <tr> 
      <td></td> 
      <td><form:hidden path="id" /></td> 
     </tr> 

     <tr> 
      <td><form:label path="title">Title:</form:label></td> 
      <td><form:input path="title" size="80" /></td> 
      <td><form:errors path="title" cssClass="error" /></td> 
     </tr> 

    [snip] 
    </table> 

    <table> 
    </table> 

    <table> 
     <c:forEach items="${offerAttribute.filters}" var="filter"> 
      <tr> 
       <td><form:checkbox 
         path="filters" 
         label="${filter.text}" 
         value="${filter.id}" 
         checked="${filter.owned ? 'true' : ''}" /> 
       </td> 
      </tr> 
     </c:forEach> 
    </table> 
    [snip] 

Отображаемый веб-страница отображается три фильтра флажков, только с середины флажком залитой

enter image description here

.

Для возвращаемого списка я ожидаю, что сервер получит только средний флажок, который я хочу.

Вот что сгенерированные флажков выглядеть как источник:

<table style="border: 1px solid; width: 100%; text-align:left;"> 
     <tr> 
      <td> 
       <input id="filters1" name="filters" type="checkbox" value="1"/> 
       <label for="filters1">Adults (18+) desired, please</label> 
       <input type="hidden" name="_filters" value="on"/> 
      </td> 
     </tr> 
     <tr> 
      <td> 
       <input id="filters2" name="filters" checked="true" type="checkbox" value="2"/> 
       <label for="filters2">Quiet audiences, please</label> 
       <input type="hidden" name="_filters" value="on"/> 
      </td> 
     </tr> 
     <tr> 
      <td> 
       <input id="filters3" name="filters" type="checkbox" value="4"/> 
       <label for="filters3">Filter Text First</label> 
       <input type="hidden" name="_filters" value="on"/> 
      </td> 
     </tr> 
</table> 

Мой флажок установлен, и в HTML. Чтобы переформулировать мой вопрос,

Почему значение checkbox не видно в обработчике POST контроллера?

Спасибо за любые ответы,

Джером.

ответ

0

После много исследований в сети и различных сеансов отладки, я придумал конфигурацию, с которой я могу жить.

В моем контроллере я предоставляю атрибут model "filterList", содержащий List. «OfferAttribute» - это объект Offer, содержащий фильтры List.

мнение имеет такую ​​последовательность:

<table> 
    <c:forEach items="${filterList}" var="filter" varStatus="status"> 
     <tr> 
      <td><input type="checkbox" name="filters[${status.index}].id" 
       value="${filter.id}" 
       ${filter.owned ? 'checked' : ''} /> ${filter.text} 
      </td> 
     </tr> 
    </c:forEach> 
</table> 

Когда POST выполняется список ownerAttribute.filters столь же долго, как оригинальный filterList объект, который создал флажки. Проверенные содержат значение Filter.id. Непроверенные содержат нуль. (То есть список возвращенных фильтров «разрежен».) Если пользователь нажимает только на несколько флажков, тогда я должен проанализировать возвращенный список, чтобы найти те, которые были выбраны.

Как только я узнаю значения идентификаторов фильтров, я выберу каждый из них через Hibernate, поместив их в восстановленный объект Offer и затем сохраняю их в базе данных.

Я понимаю, что я не (в настоящее время) использую форму: checkbox. Но это работает, и я нажимаю на это время. Я вернусь позже, возможно, и посмотрю, какая форма: checkbox может сделать для меня.

0

Значения флажков не могут быть напрямую привязаны к списку.

Для этого вам нужно создать простой файл данных pojo, который будет хранить значения полей формы в jsp. И в этом databean для привязки значений вам нужно объявить int[] filterId, и значения ваших флажков будут привязаны в этом массиве.

Надеюсь, это вам поможет.

+0

Класс моего предложения, по-видимому, является формой для страницы. Когда у меня нет списка флажков, я могу добавлять и обновлять объекты предложения в БД. Моя проблема заключается в добавлении списка флажков в сторону. Я могу добавить int [] filterIds в качестве @Transient, чтобы флажки привязывались к filterIds, а затем обрабатывали результат через код сервера. Это то, что вы предлагаете здесь? –

+0

Вы добавляете новые флажки с использованием javascript? –

+0

В этом случае вам нужно использовать LazyList. –

 Смежные вопросы

  • Нет связанных вопросов^_^