2014-11-10 15 views
6

Я довольно новичок в Spring MVC, поэтому, пожалуйста, будьте спокойны.Spring MVC форма не поддерживается модельным объектом

Я имею трудность, чтобы понять, как достичь следующих требований в Spring MVC:

  • JSP форма списка, чтобы получить список пользователей из базы данных (сервис, хранилище вещь работает должным образом).
  • Форма не поддерживается объектом атрибута модели. Это список/форму поиска!
  • Мне нужно получить список пользователей, соответствующие определенным критериям, взятые из нескольких «фильтров» таких областях, как:
    • области (выпадающий список)
    • архивируется пользователь? (Да/нет выпадающего списка)

userList.jsp

<spring:url value="strFormAction" var="/rest/security/user/list" /> 
<form:form id="userListForm" method="GET" action="${strFormAction}" modelAttribute="user"> 

<form:select id="strRegionId" path="${strRegionId}" cssClass="form-control" onchange="updateUsersList('1');"> 
    <spring:message var="strSelectRegionLabel" code="select.region" />       
    <form:option value="0" label="${strSelectRegionLabel}" /> 
    <form:options items="${regions}" itemValue="intId" itemLabel="strNameFr" /> 
</form:select> 

<form:select id="strArchived" path="${strArchived}" cssClass="form-control"> 
    <spring:message var="strYesLabel" code="yes" /> 
    <form:option value="true" label="${strYesLabel}"/> 

    <spring:message var="strNoLabel" code="no" /> 
    <form:option value="false" label="${strNoLabel}"/> 
</form:select> 

<table> 

... 

<c:forEach items="${users}" var="user"> 
...rows generated here... 
</c:forEach> 
... 
</table> 

</form:form> 

UserController.java

@RequestMapping(value = "/list", method = RequestMethod.GET) 
public String processUserList( @ModelAttribute("user") User user, 
           @RequestParam(value = "strRegionId", required = false) String strRegionId, 
           @RequestParam(value = "strArchived", required = false) String strArchived, 
           @RequestParam(value = "strSortBy", required = false) String strSortBy, 
           Model model) { 

    int intRegionId = strRegionId != null && strRegionId.equals("0") == false ? Integer.valueOf(strRegionId) : 0; 
    boolean booArchived = strArchived != null && strArchived.length() > 0 ? Boolean.valueOf(strArchived) : false;  
    int intSortBy = strSortBy != null && strSortBy.length() > 0 ? Integer.valueOf(strSortBy) : 1; 

    List<Region> regions = this.locationService.lstRegions(); 
    model.addAttribute("strRegionId", String.valueOf(intRegionId)); 
    model.addAttribute("strArchived", String.valueOf(booArchived)); 
    model.addAttribute("strSortBy", String.valueOf(intSortBy)); 

    List<User> users = this.securityService.listUsersByRegionAndArchiveState(intRegionId, booArchived, intSortBy); 

    model.addAttribute("user", new User()); 
    model.addAttribute("users", users); 
    model.addAttribute("regions", regions); 

    return "user/userList"; 
} 

Это не кажется, что я не могу использовать пружинную форму TagLib на все без предоставления атрибута modelAttribute в форме. Я тогда поставил манекен modelAttribute от моего контроллера, но теперь я получаю:

javax.servlet.ServletException: javax.servlet.jsp.JspException: org.springframework.beans.NotReadablePropertyException: Invalid свойство «0» класса боба [spring4base.model.security.User]: Свойство Bean '0' не читается или имеет недопустимый метод getter: соответствует ли тип возвращаемого значения getter типу параметра setter?

Как я уже говорил, эта страница не предназначена для поддержки каких-либо конкретных POJO. Это страница поиска, которая должна возвращать список пользователей (компонент User entity) на основе выбранных ранее фильтров (регион, архивированное состояние). Форма должна отправляться на себя каждый раз при изменении выпадающего списка (пользователь выбирает регион, отправка выполняется по одному и тому же сопоставлению, а затем список пользователей перезагружается только пользователями из этого конкретного региона).

Я пришел из Struts 1, в котором нам нужно было создать ActionForm для каждой отдельной страницы. Из того, что я читал из документации, формы не нужны в эти дни, поэтому я действительно с нетерпением жду фиксации этой проблемы.

Любая помощь была бы принята с благодарностью.

ответ

4

Я бы просто создать вспомогательный класс, содержащий ваши критерии поиска, например:

public class UserSearchCriteria { 
    private String regionId; 
    private Boolean archived; 
    private String sortBy; 

    // Getters and setters 
} 

Затем я хотел бы изменить свой метод контроллера, как это (некоторый код отсутствует, но это должно дать вам идею).

@RequestMapping(value = "/list", method = RequestMethod.GET) 
public String processUserList(@ModelAttribute("searchCriteria") UserSearchCriteria userSearchCriteria, Model model) { 
    // Retrieve users and perform filtering based on search criteria 
    List<User> users = this.securityService.listUsers(searchCriteria); 

    model.addAttribute("users", users); 
    model.addAttribute("regions", regions); 

    return "user/userList"; 
} 

И тогда вы будете использовать вашу форму фильтрации, как это:

<spring:url value="/rest/security/user/list" var="formAction" /> 
<form:form id="userListForm" method="GET" action="${formAction}" modelAttribute="searchCriteria"> 

<form:select path="regionId" cssClass="form-control" onchange="updateUsersList('1');"> 
    <spring:message var="strSelectRegionLabel" code="select.region" />       
    <form:option value="0" label="${strSelectRegionLabel}" /> 
    <form:options items="${regions}" itemValue="intId" itemLabel="strNameFr" /> 
</form:select> 

<form:select path="archived" cssClass="form-control"> 
    <spring:message var="strYesLabel" code="yes" /> 
    <form:option value="true" label="${strYesLabel}"/> 

    <spring:message var="strNoLabel" code="no" /> 
    <form:option value="false" label="${strNoLabel}"/> 
</form:select> 

У вас было несколько ошибок в форме в вашем фрагменте кода. Например, атрибут path принимает строку, содержащую имя (или путь) свойства для привязки, вы передавали ему некоторую переменную.Также у вас было value и var Включено в ваш <spring:url> Я думаю.

Попробуйте, это не полное решение, но, надеюсь, оно даст вам некоторые указания о том, как это реализовать. Если у вас возникнут проблемы, оставьте комментарий, и я обновлю ответ.

+0

Этот ответ является единственным в своем роде. Это работает как шарм. Большое спасибо за быстрый ответ. –

+0

Что вы понимаете, переместив логику фильтрации на уровень службы/репозитория? Пользователь должен иметь возможность выбирать параметр сортировки из datagrid (список пользователей). Предположим, он нажимает на заголовок таблицы «Имя», запрос должен быть упорядочен по порядку сортировки по имени. Вы имеете в виду, что я должен создать несколько небольших методов, таких как «listUsersSortedByFirstName», которые все бы использовали один и тот же закрытый метод в конце? Любые советы с вашей стороны будут высоко оценены. –

+1

Да, теперь, когда я смотрю на него, вы, вероятно, делаете фильтрацию на своем сервисном уровне. Я написал это в спешке и, посмотрев на метод контроллера, я, вероятно, подумал, что вы фильтруете его на контроллере. В любом случае я бы просто создал один метод listUsers() на вашей службе и передал ему объект критериев поиска, который может быть самым чистым решением. Я удалю ненужную часть из ответа ... –

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