Home > database >  Sping MVC, Thymeleaf, POST request, how to pass list of objects to controller
Sping MVC, Thymeleaf, POST request, how to pass list of objects to controller

Time:09-29

A "teacher" can have several assigned "subjects" to teach:

public class Teacher {
    private int id;
    private String firstName;
    private String lastName;
    ...
    private List<Subject> subjects;
}

In HTML view user can select one ore more subjects for the teacher and send POST request:

<select class="form-control" id="subjects" name="subjects" size="5" multiple required>
   <option th:each="subject: ${allSubjects}"
       th:value="${subject.id}"
       th:text="${subject.name}"
       th:selected="${teacher.subjects.contains(subject)}">
   </option>
</select>

Controller to process this request:

@PostMapping("/update")
    public String update(@ModelAttribute("teacher") Teacher teacher) {
        logger.debug("Received update data: {}", teacher);
        teacherService.update(teacher);
        return "redirect:/teachers";
    }

Here is the POST request that is being passed:

enter image description here

I expect Spring to take subject.id`s and inject them into teacher as list of subjects. But I get exception:

BindException

org.springframework.validation.BeanPropertyBindingResult: 
1 errors Field error in object 'teacher' on field 'subjects': rejected value [2,4]; codes [typeMismatch.teacher.subjects,typeMismatch.subjects,typeMismatch.java.util.List,typeMismatch]; 
arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [teacher.subjects,subjects]; 
arguments []; default message [subjects]]; default message [Failed to convert property value of type 'java.lang.String[]' to required type 'java.util.List' for property 'subjects'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'ua.com.foxminded.university.model.Subject' for property 'subjects[0]': no matching editors or conversion strategy found]

I carefully read first 50 google results for my question, code should work, but it doesn't. I must be missing something.

CodePudding user response:

First of all wrong annotation - u dont use @ModelAttribute inside of the post but rather @RequestBody which is implicit in spring controllers for post.

Other than that what you are sending is not a teacher entity but rather teacherDTO which wont have all the fields (collections) that teacher entity that you showed has. That means you should be receiving a different class (TeacherDTO) and then convert it correctly to teacher entity which you then update in the database

CodePudding user response:

i suppose this is an update form, so it take an object teacher as an input. try this


<form th:object="${teacher}" method="post">
<select class="form-control" th:field="*{subjects}" id="subjects" name="subjects" size="5" multiple required>
   <option th:each="subject: ${allSubjects}"
       th:value="${subject.id}"
       th:text="${subject.name}"
       th:selected="*{subjects.contains(subject)}">
   </option>
</select>
</form>
  • Related