Ошибка при попытке включить свойство объекта в ‹form:hidden/› со списком объектов в modelAttribute

Я работаю над весенним проектом mvc. У меня есть представление, в котором я перечисляю все объекты типа Person. Список успешно отображается со всеми атрибутами. Однако, поскольку теперь мне нужно передать отдельный объект обратно в контроллер после выбора пользователем, я заключил свой список в тег формы, чтобы я мог связать его с атрибутом модели и отправить объект обратно в контроллер. Когда я пытаюсь включить поле form:hidden для привязки атрибута, я получаю следующую ошибку:

ОШИБКА oswstags.form.HiddenInputTag — Недопустимое свойство «uid» класса компонента [java.util.ArrayList]: свойство «uid» компонента недоступно для чтения или имеет недопустимый метод получения: тип возвращаемого значения метода получения соответствует типу параметра сеттера? org.springframework.beans.NotReadablePropertyException: недопустимое свойство «uid» класса компонента [java.util.ArrayList]: свойство «uid» компонента не читается или имеет недопустимый метод получения: соответствует ли возвращаемый тип получателя типу параметра сеттера?

Все сеттеры и геттеры существуют для объекта Person, и атрибуты успешно отображаются, если я не включаю форму: скрыто

Модель:

public class Person {

Integer id;

String uid;

String fullname;

String firstname;

String lastname;

String fathername;

String email;

String status;  

List<String> environments;

List<String> institutions;

public boolean isNew() {
    return (this.id == null);
}

public Integer getId() {
    return id;
}

public void setId(Integer id) {
    this.id = id;
}

public String getUid() {
    return uid;
}

public void setUid(String uid) {
    this.uid = uid;
}

public String getFullname() {
    return fullname;
}

public void setFullname(String fullname) {
    this.fullname = fullname;
}

public String getFirstname() {
    return firstname;
}

public void setFirstname(String firstname) {
    this.firstname = firstname;
}

public String getLastname() {
    return lastname;
}

public void setLastname(String lastname) {
    this.lastname = lastname;
}

public String getFathername() {
    return fathername;
}

public void setFathername(String fathername) {
    this.fathername = fathername;
}

public String getEmail() {
    return email;
}

public void setEmail(String email) {
    this.email = email;
}

public String getStatus() {
    return status;
}

public void setStatus(String status) {
    this.status = status;
}


public List<String> getEnvironments() {
    return environments;
}

public void setEnvironments(List<String> environments) {
    this.environments = environments;
}
public List<String> getInstitutions() {
    return institutions;
}

public void setInstitutions(List<String> institutions) {
    this.institutions = institutions;
}
}

Контроллер:

@RequestMapping(value = "/persons/search", method = RequestMethod.POST)
public String listPersons(@RequestParam("searchString") String searchStr, Model model) {

logger.debug("listPersons()");
userService.initialize();
myPersons = userService.searchPersons(searchStr);
model.addAttribute("persons", myPersons);
return "users/listPersons";
}

Просмотр (listPersons.jsp)

<%@ page session="false"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>

<!DOCTYPE html>
<html lang="en">

<jsp:include page="../fragments/header.jsp" />

<body>

<div class="container">

    <c:if test="${not empty msg}">
        <div class="alert alert-${css} alert-dismissible" role="alert">
            <button type="button" class="close" data-dismiss="alert" aria-label="Close">
                <span aria-hidden="true">&times;</span>
            </button>
            <strong>${msg}</strong>
        </div>
    </c:if>

    <h1>All Persons</h1>

    <table class="table table-striped">
        <thead>
            <tr>
                <th>ID</th>
                <th>UID</th>
                <th>Full Name</th>
                <th>Email</th>
                <th>Institutions</th>
                <th>Environments</th>
                <th>Action</th>
            </tr>
        </thead>
    <spring:url value="/persons/cards" var="showPersonCardsUrl" />
    <form:form method="post" action="${showPersonCardsUrl}" modelAttribute="persons">
        <c:forEach var="person" items="${persons}" varStatus="status">
            <tr>
                <td>
                    ${person.id}
                </td>
                <td>${person.uid}</td>
                <form:hidden path="uid" />
                <td>${person.fullname}</td>
                <td>${person.email}</td>
                <td><c:forEach var="institution" items="${person.institutions}" varStatus="loop">
                    ${institution}
                    <c:if test="${not loop.last}">,</c:if>
                    </c:forEach>
                </td>
                <td><c:forEach var="environment" items="${person.environments}" varStatus="loop">
                    ${environment}
                    <c:if test="${not loop.last}">,</c:if>
                    </c:forEach>
                </td>
                <td>
                    <spring:url value="/persons/${person.uid}" var="showPersonUrl" />
                    <spring:url value="/persons/${person.uid}/delete" var="deletePersonUrl" /> 
                    <spring:url value="/persons/${person.uid}/update" var="updatePersonUrl" />
                    <spring:url value="/persons/${person.uid}/cards" var="showPersonCardsUrl" />

                    <button class="btn btn-info" onclick="location.href='${showPersonUrl}'">Query</button>
                    <button class="btn btn-primary" onclick="location.href='${updatePersonUrl}'">Update</button>
                    <button class="btn btn-danger" onclick="this.disabled=true;post('${deletePersonUrl}')">Delete</button>
                    <button class="btn btn-info" type="submit">Cards</button>
                </td>
            </tr>
        </c:forEach>
    </form:form>
    </table>

</div>

<jsp:include page="../fragments/footer.jsp" />

</body>
</html>

Вместо

<form:hidden path="uid" />

я тоже пробовал

<form:hidden path="persons.person.uid"/>

а также это

<form:hidden path="users[${status.index}].uid"/>

но ничего не работает. Мне нужно передать объект человека обратно контроллеру с его uid, чтобы я мог выполнять дальнейшую обработку. Что я могу делать не так в этом?


person js.hrt    schedule 07.09.2019    source источник


Ответы (1)


Тег скрытой формы попытается разрешить путь из modelAttribute в теге from, внутри которого он находится, например, ваш modelAttribute — это persons, таким образом, скрытая форма попытается получить доступ к persons.uid, и если вы используете persons.person.uid, она будет преобразована в persons.persons.person.uid и так далее.

В вашем случае я предлагаю использовать обычный ввод:

<input type="hidden" name="persons[${status.index}]" value="${person.uid}"/>

При этом, когда форма будет отправлена, она отправит массив с именами людей со значениями uid внутри каждого.

Если вы по-прежнему настаиваете на использовании <form:hidden>, вам нужно пересмотреть способ построения формы.

person Sari Alalem    schedule 07.09.2019
comment
Хорошо, спасибо, понял. Я попробую с этим обычным вводом - person js.hrt; 07.09.2019