Я не могу передать много объектов через контроллер ((( - PullRequest
0 голосов
/ 24 апреля 2020

Когда я пытаюсь передать много данных через контроллер, я получаю сообщение об ошибке:

Произошла непредвиденная ошибка (тип = Bad Request, status = 400). Не удалось преобразовать значение типа 'java .lang.String' в требуемый тип 'com.psu.projectmethod.domain.wrappers.UserSet'; вложенным исключением является org.springframework.core.convert.ConversionFailedException: не удалось преобразовать тип [java .lang.String] в тип [@ org.springframework.web.bind.annotation.ModelAttribute com.psu.projectmethod.domain. wrappers.UserSet] для значения 'com.psu.projectmethod.domain. User@23'; вложенное исключение java .lang.IllegalArgumentException: не удалось создать экземпляр Тип коллекции: com.psu.projectmethod.domain.wrappers.UserSet org.springframework.beans.TypeMismatchException: не удалось преобразовать значение типа 'java .lang.String 'к необходимому типу' com.psu.projectmethod.domain.wrappers.UserSet '; вложенным исключением является org.springframework.core.convert.ConversionFailedException: не удалось преобразовать тип [java .lang.String] в тип [@ org.springframework.web.bind.annotation.ModelAttribute com.psu.projectmethod.domain. wrappers.UserSet] для значения 'com.psu.projectmethod.domain. User@23'; Вложенное исключение: java .lang.IllegalArgumentException: Не удалось создать экземпляр Тип коллекции: com.psu.projectmethod.domain.wrappers.UserSet

Я сделал все в соответствии с примерами из stackoverflow и на основе этой статьи https://www.viralpatel.net/spring-mvc-multi-row-submit-java-list/. Пожалуйста, помогите мне решить эту проблему ((

Мои методы контроллера:

@PreAuthorize("hasAuthority('_2_TEACHER')")
@GetMapping("/project/{projectId}/party/create")
public String viewTeacherCreateProjectParty(
        @PathVariable("projectId") Project project,
        Party party,
        Model model) {
    Set<User> users = userService.userList(Sort.by("username"));
    UserSet userSet = new UserSet(users);
    model.addAttribute("project", project);
    model.addAttribute("party", party);
    model.addAttribute("users", userSet.getUsers());
    return "teacherProjectPartyCreate";
}

@PreAuthorize("hasAuthority('_2_TEACHER')")
@PostMapping("/project/{projectId}/party/create")
public String processCreateProjectParty(
        @PathVariable("projectId") Project project,
        @Valid Party party,
        @ModelAttribute("users") UserSet users,
        Model model) {
    model.addAttribute("project", project);
    model.addAttribute("party", party);
    Long projectId = projectService.createProjectParty(project, party, users);
    return "redirect:/projects/project/" + projectId;
}

Форма бесплатного маркера:

<form action="/projects/project/${project.projectId}/party/create" method="post"
                          style="color: #757575;">

                        <!-- CSRF Token -->
                        <input type="hidden" name="_csrf" value="${_csrf.token}"/>

                        <div class="md-form">
                            <input type="text" id="partyName" name="partyName" value="${party.partyName!''}"
                                   class="form-control ${(partyNameError??)?string('is-invalid', '')}" required>
                            <label for="partyName">Group name</label>
                            <#if partyNameError??>
                                <div class="invalid-feedback">
                                    ${partyNameError}
                                </div>
                            </#if>
                        </div>

                        <select name="users" class="selectpicker"
                                data-header="Select users"
                                data-live-search="true"
                                data-selected-text-format="count"
                                data-size="auto"
                                data-style="btn-unique"
                                data-width="auto"
                                multiple
                                title="Select users"
                        >
                            <#list users as user>
                                <option value="${user}">${user.fullname}</option>
                            </#list>
                        </select>

                        <div class="modal-footer d-flex justify-content-center">

                            <button type="button" onClick='location.href="/projects/project/${project.projectId}"'
                                    class="btn btn-outline-info waves-effect">
                                Отмена
                            </button>

                            <button type="submit" class="btn btn-primary waves-effect">
                                Save
                            </button>

                        </div>

                    </form>

Метод создания моей сущности

public Long createProjectParty(Project project, Party party, Set<User> users) {
    project.addParty(party);
    party.addUsers(party, users);
    projectRepo.save(project);
    return project.getProjectId();
}

Вспомогательные методы для добавления двунаправленных ассоциаций:

public void addParty(Party party) {
    party.setPartyProject(this);
    this.projectParties.add(party);
}

public void addUsers(Party party, Set<User> users) {
    party.setPartyUsers(users);
    this.partyUsers.addAll(users);
}

Отображение ассоциации ManyToMany:

@ManyToMany(fetch = FetchType.LAZY,
        cascade = {CascadeType.PERSIST, CascadeType.DETACH, CascadeType.REFRESH, CascadeType.REMOVE}
)
@JoinTable(name = "party_users",
        joinColumns = {@JoinColumn(name = "fk_party_id")},
        inverseJoinColumns = {@JoinColumn(name = "fk_user_id")})
private Set<User> partyUsers = new HashSet<>();

public class UserSet implements Set<User> {
private Set<User> users;

public UserSet(Set<User> users) {
    this.users = users;
}

public Set<User> getUsers() {
    return users;
}

public void setUsers(Set<User> users) {
    this.users = users;
}
... // getters, setters and Set metods 

Ответы [ 2 ]

0 голосов
/ 24 апреля 2020

Я не видел определения всех ваших классов, но на деле это кажется произвольным и странным вместе.

См. Com.psu.projectmethod.domain.wrappers.UserSet] для значения 'com.psu.projectmethod.domain. User@23'; Вложенное исключение: java .lang.IllegalArgumentException: Не удалось создать экземпляр Тип коллекции: com.psu.projectmethod.domain.wrappers.UserSet
1. Почему Spring должен иметь возможность преобразовывать в пользовательский тип из String?
2. См. «Для значения» com.psu.projectmethod.domain. User@23 '; вложенное исключение: java .lang.IllegalArgumentException: Не удалось создать экземпляр Тип коллекции: com.psu.projectmethod.domain.wrappers.UserSet "
Почему он пытается создать экземпляр UserSet при работе с экземпляром User@23? Как ModelAndView знает о вашем типе UserSet, почему он упомянул об этом? У вас есть циклические c ссылки? Пожалуйста, внимательно проверьте, что вы передаете в модель и что происходит при конвертации.

0 голосов
/ 24 апреля 2020

После анализа ваших журналов я обнаружил, что с вашим запросом что-то не так.

Внимательно прочитайте эту запись журнала:

Failed to convert value of type 'java.lang.String' to required type 'com.psu.projectmethod.domain.wrappers.UserSet'

Кажется, вы пытаетесь отправить String в том месте, где ожидается UserSet. Если такое поведение желательно, пожалуйста, подумайте об использовании конвертеров. Проверьте артикул

...