0

I trying to add validation to phone number input but i stuck at resolving this error when accessing index.

The error message

Caused by: org.attoparser.ParseException: Error during execution of processor 'org.thymeleaf.spring5.processor.SpringInputGeneralFieldTagProcessor' (template: "index" - line 76, col 73)

Caused by: java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'phonenumber' available as request attribute

index.html

 <div class="myForm">
            <form th:action="@{/save}"  method="post" th:object="${phonebook}">
            <div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
                <div class="modal-dialog" role="document">
                    <div class="modal-content">
                        <div class="modal-header">
                            <h5 class="modal-title" id="exampleModalLabel">Update or Create</h5>
                            <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                                <span aria-hidden="true">&times;</span>
                            </button>
                        </div>
                        <div class="modal-body">
                            <div class="form-group">
                                <input type="hidden" class="form-control" id="id" name="id" value=""/>
                            </div>
                            <div class="form-group">
                                <label for="surname" class="col-form-label">Surname:</label>
                                <input type="text" class="form-control" id="surname" name="surname" value=""/>
                            </div>
                            <div class="form-group">
                                <label for="firstname" class="col-form-label">First Name:</label>
                                <input type="text" class="form-control" id="firstname" name="firstname" value=""/>
                            </div>
                            <div class="form-group">
                                <label for="phonenumber" class="col-form-label">Phone Number:</label>
                                <input type="text" class="form-control" th:field="*{phonenumber}" id="phonenumber" name="phonenumber" value=""/>
                                <span th:if="${#fields.hasErrors('phonenumber')}" class="help-block" th:errors="*{phonenumber}"></span>
                            </div>

                        </div>
                        <div class="modal-footer">
                            <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                            <input type="submit" class="btn btn-primary" value="Save"/>
                        </div>
                    </div>
                </div>
            </div>
        </form>

Controller

@RequestMapping(value = {"/"}, method = RequestMethod.GET)
public String showPage(Model model, @RequestParam(defaultValue = "0") int page) {
    model.addAttribute("data", phonebookRepository.findAll(PageRequest.of(page, 10)));
    model.addAttribute("currentPage", page);
    return "index";
}

@PostMapping("/save")
public String save(@Valid Phonebook p, BindingResult bindingResult) {

    if (bindingResult.hasErrors()) {
        return "redirect:/";
    }else {
        phonebookRepository.save(p);
    }
    return "redirect:/";
}

Phonebook

     @Entity
        @Table(name = "Phonebook")
        public class Phonebook {

            @Id
            @GeneratedValue(strategy = GenerationType.AUTO)
            @Column(name = "id")
            private Integer id;
            @NotNull
            @Size(max=15, message = "Max symbols is 15")
            @Column(name = "phonenumber", length = 15, nullable = false)
            private String phonenumber;
            @Column(name = "surname", length = 50, nullable = false)
            private String surname;
            @Column(name = "firstname", length = 50, nullable = false)
            private String firstname;

//getters and setter
Ekera
  • 69
  • 1
  • 3
  • 10

1 Answers1

1

I've got 2 approach to get this issue solve :--

1.) use @RequestParam to get the Phonebook Object like this :--

@PostMapping("/save")
public String save(@Valid @RequestParam("phonenumber")String phonenumber, BindingResult bindingResult) {

    if (bindingResult.hasErrors()) {
        return "redirect:/";
    }else {
        phonebookRepository.save(p);
    }
    return "redirect:/";
}

OR -- Use @ModelAttribute to get the values of your form, like this :--

1.) create a new Phonebook object and add in model attribute :-

     @RequestMapping(value = {"/"}, method = RequestMethod.GET)
        public String showPage(Model model, @RequestParam(defaultValue = "0") int page) {

            //your code 

            model.addAttribute("phoneBook", new Phonebook());
            return "index";
        }

2.) Changes in your Thymeleaf / HTML page (use th:object to send your Phonebook object after submit) :--

<form th:action="@{/save}"  method="post" th:object="${phoneBook}">

// your code

</form>

3.) Then Use @ModelAttribute to bind the values like this :--

@PostMapping("/save")
public String save(@Valid @ModelAttribute("phoneBook")Phonebook p, BindingResult bindingResult) {

    if (bindingResult.hasErrors()) {
        return "redirect:/";
    }else {
        phonebookRepository.save(p);
    }
    return "redirect:/";
}

4.) And finally your Phonebook class with getter & setter Methods.

Sumit
  • 917
  • 1
  • 7
  • 18
  • Your solution fixes old errors but generates new one org.attoparser.ParseException: (Line = 52, Column = 13) Incomplete structure: "
    – Ekera Jun 19 '18 at 13:46
  • Have you closed your form with tag properly ? – Sumit Jun 19 '18 at 13:48
  • @Ekera you're missing a `"` after `"${phonebook}` – chelmertz Jun 19 '18 at 13:54
  • @chelmertz fixed but then it causes old errors described above – Ekera Jun 19 '18 at 13:57
  • @Sumit yes it's closed – Ekera Jun 19 '18 at 13:59
  • @Ekera make sure that you're using correct spelling and it has to be same while adding it to **mode.addAttribute("phoneBook", new Phonebook())** and on thymeleaf form **th:object="${phoneBook}">** and then on your other controller where you're getting the Phonebook Value:- **@ModelAttribute("phoneBook")Phonebook p** – Sumit Jun 19 '18 at 14:04
  • @Sumit Now it works, but i dont get any error message when i hit Save button with max then 15 symbols – Ekera Jun 19 '18 at 14:09
  • Its because you haven't use any error message in your **hasError** method and you're redirecting your page when you're code is going in **hasError** method :--- ** if(result.hasErrors()){ model.put("message", "Invalid Phone Number"); model.addAttribute("phoneBook", new Phonebook()); return "index"; //your your page where you want to display error }** – Sumit Jun 19 '18 at 14:13
  • There is no "put" in my version of spring boot – Ekera Jun 19 '18 at 14:31
  • @Sumit I added but it does not have "put" public String save(Model model, Valid ModelAttribute("phoneBook")Phonebook p, BindingResult bindingResult)** – Ekera Jun 19 '18 at 14:41
  • @Ekera my sincere apologies its actually a method in **ModelMap class** So use :-- public String save(ModelMap model, Valid ModelAttribute("phoneBook")Phonebook p, BindingResult bindingResult) – Sumit Jun 19 '18 at 15:41