[SOLVED] spring boot & thymeleaf. Date w formularzu

0

Cześć,
od niedawna zacząłem programować w Java i spring boot.
Na razie jestem na etapie prostej stronki zużyciem Spring MVC i thymeleaf.

Podczas próby dodania do formularza pola z wyborem daty dostaje error:

2016-12-29 11:12:47.260 ERROR 9344 --- [nio-8080-exec-1] org.thymeleaf.TemplateEngine             : [THYMELEAF][http-nio-8080-exec-1] Exception processing template "student_form": Error during execution of processor 'org.thymeleaf.spring4.processor.attr.SpringInputGeneralFieldAttrProcessor' (student_form:19)
2016-12-29 11:12:47.270 ERROR 9344 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateProcessingException: Error during execution of processor 'org.thymeleaf.spring4.processor.attr.SpringInputGeneralFieldAttrProcessor' (student_form:19)] with root cause

org.springframework.beans.NotReadablePropertyException: Invalid property 'birthdate' of bean class [com.lama.Entity.Student]: Bean property 'birthdate' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?

Formularz:

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Add Student</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"></link>
</head>
<body>
<div th:include="components/header"></div>
<div class="container">
    <h1>Form</h1>
    <!--  -->
    <form action="#" th:action="@{insert}" th:object="${student}" method="post">
        <p>Id: <input type="text" th:field="*{id}" /><span style="color: red;" th:if="${#fields.hasErrors('id')}" th:errors="*{id}"></span></p>
        <p>Name: <input type="text" th:field="*{name}" /><span style="color: red;" th:if="${#fields.hasErrors('name')}" th:errors="*{name}"></span></p>
        <p>Course: <input type="text" th:field="*{course}" /><span style="color: red;" th:if="${#fields.hasErrors('course')}" th:errors="*{course}"></span></p>
        <p>Email: <input type="text" th:field="*{email}" /><span style="color: red;" th:if="${#fields.hasErrors('email')}" th:errors="*{email}"></span></p>
        <p>Birthdate: <input type="text" th:field="*{{birthdate}}"/><span style="color: red;" th:if="${#fields.hasErrors('birthdate')}" th:errors="*{birthdate}"></span></p>
        <p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
    </form>
</div>
</body>
</html>

Kontroler:

@Controller
@RequestMapping("/students")
public class StudentController implements HandlerExceptionResolver {

    @Autowired // no need to use new clause
    private StudentService studentService;

    @GetMapping( value={"/add","/insert"}) // students/add or /students/insert
    public String getForm(Model model) {
        model.addAttribute("student", new Student());
        return "student_form";
    }
    @PostMapping( value={"/add","/insert"}) // students/add or /students/insert
    public String submitForm(@Valid @ModelAttribute  Student student, BindingResult results) {
        if (results.hasErrors())
            return "student_form";
        this.studentService.insertStudent(student);
        return "result";
    }
    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        ModelAndView mav = new ModelAndView("error");
        mav.addObject("error", ex.getMessage());
        mav.addObject("error2", ex.getStackTrace());
        return mav;
    }
}

DAO:

@Repository
@Qualifier("fakeData") //used to quick switch betwean databases. That in service you choose actual implementation of interface
public class FakeStudentDao implements StudentDao {

    private static Map<Integer, Student> students;
    static {
        students = new HashMap<Integer, Student>(){
            {
                put(1, new Student(1,
                        "Roman Zioło",
                        "Kurs Gotowania",
                        "[email protected]",
                        "14/01/1994"));
                put(2, new Student(2,
                        "Zbigniew Kieł",
                        "Kurs 3",
                        "[email protected]",
                        "22/05/1922"));
                put(3, new Student(3,
                        "Tomasz Kowalewski",
                        "Kurs Y",
                        "[email protected]",
                        "30/11/2000"));

            }
        };
    }
    @Override
    public Collection<Student> getAllStudents(){
        return this.students.values();
    }
    @Override
    public Student getStudentById(Integer id) {
        return this.students.get(id);
    }

    @Override
    public void removeStudentById(Integer id) {
        this.students.remove(id);
    }

    @Override
    public void updateStudent(Student s) {
        Student student = students.get(s.getId());
        student.setCourse(s.getCourse());
        student.setName(s.getName());
        this.students.put(student.getId().intValue(), student);
    }

    @Override
    public void insertStudent(Student s) {
        this.students.put(s.getId().intValue(), s);
    }
}

Entity:

public class Student {

    @NotNull
    private Integer id;

    @NotNull
    @Size(min = 2, max = 30)
    private String name;

    @NotNull
    @Size(min = 10, max = 255)
    private String course;

    @NotNull
    @Email
    private String email;

    @DateTimeFormat(pattern = "dd/MM/yyyy")
    @NotNull
    @Past
    private Date birthday;

    public Student(Integer id, String name, String course, String email, String birthdate) {
        this.id = id;
        this.name = name;
        this.course = course;
        this.email = email;
        setBirthdayFromStr(birthdate);
    }
    public Student(Integer id, String name, String course, String email, Date birthdate) {
        this.id = id;
        this.name = name;
        this.course = course;
        this.email = email;
        this.birthday =birthdate;
    }

    public Student() {
    }

    public Integer getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public String getCourse() {
        return course;
    }

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

    public void setName(String name) {
        this.name = name;
    }

    public void setCourse(String course) {
        this.course = course;
    }

    public String getEmail() {
        return email;
    }

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


    public void setBirthdayFromStr(String birthday) {
        SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
        try {
            this.birthday = formatter.parse(birthday);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
}

Pomożecie w tej kwestii. Wszelkie próby googlowania póki co nie przyniosły efektu.

0

Cześć,

W formularzu zdefiniowales pole, ktore jest powiazane ze zmienna birthdate klasy Student. Problem polega na tym, ze w klasie Student nie ma pola birthdate (jest birthday). Zmien albo formularz albo klase Student tak, zeby wszedzie bylo to samo. Ponadto miej na uwadze, ze wielkosc liter moze miec znaczenie.

Jeżeli zmienisz kod klasy Student to gettery i settery też oczywiście trzeba pozmieniać

0

Ale wstyd, pisać post z powodu literówki.
Nie wiem jak mogłem to przeoczyć.

Dzięki za pomoc.

1 użytkowników online, w tym zalogowanych: 0, gości: 1