validationspring-mvcjspjstl

Neither BindingResult nor plain target object for bean name 'todooo' available as request attribute


While running the insert without validation it works, but when I added validation like targetdate must be future date and trying to show in form twoway binding, then this error started.

No idea on which direction I need to think of.

Error:

2024-04-26T12:24:20.955-04:00 DEBUG 11520 --- [ToDo] [nio-8080-exec-8] o.s.web.servlet.view.JstlView            : View name 'insert', model {todo=ToDo{id=5, username='Test1, description='HelloWorld, targetDate=2020-04-26, creationDate=2024-04-26, done=false, attachment= XX}, org.springframework.validation.BindingResult.todo=org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'todo' on field 'targetDate': rejected value [2020-04-26]; codes [Future.todo.targetDate,Future.targetDate,Future.java.time.LocalDate,Future]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [todo.targetDate,targetDate]; arguments []; default message [targetDate]]; default message [springboot-starter-validation-@size---> ID -->  ALLOWED to enter only FUTURE dates ]}
2024-04-26T12:24:20.962-04:00 DEBUG 11520 --- [ToDo] [nio-8080-exec-8] o.s.web.servlet.view.JstlView            : Forwarding to [/WEB-INF/jsp/insert.jsp]
2024-04-26T12:24:21.034-04:00 ERROR 11520 --- [ToDo] [nio-8080-exec-8] o.s.web.servlet.tags.form.InputTag       : Neither BindingResult nor plain target object for bean name 'todooo' available as request attribute

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

org.apache.jasper.JasperException: An exception occurred processing [/WEB-INF/jsp/insert.jsp] at line [34]

31: 
32:             <form:form method="post" modelAttribute="todooo">
33:                 <p><label>id : </label>
34:                     <form:input type="text" path="id" required="required"   />
35: 
36:                 <p><label>username : </label>
37:                     <form:input type="text" path="username" required="required"    />
    @RequestMapping(value  = "/insert", method= RequestMethod.GET)
    public String get_insert_todo(ModelMap modelMap){
        String u_retrived = (String) modelMap.get("uid");
        Todo todo_obj = new Todo(toDo_services.listAllToDo().size()+1,u_retrived,"HelloWorld",LocalDate.now(), LocalDate.now().plusYears(1),false );

        modelMap.put("todooo", todo_obj);

        return "insert";
    }

    @RequestMapping(value  = "/insert", method= RequestMethod.POST)
    public String post_insert_data(ModelMap modelMap, @Valid Todo todooo, BindingResult bindingResult){

        if(bindingResult.hasErrors()){
            return  "insert";  
        }

        String u_retrived = (String) modelMap.get("uid");
        toDo_services.insert_todo(String.valueOf(todooo.getId()), u_retrived, todooo.getDescription(), todooo.getCreationDate(), todooo.getTargetDate(), todooo.getDone());
        return "redirect:list";
    }

    public List<Todo> insert_todo(String id,
                                  String username,
                                  String description,
                                  LocalDate creationDate,
                                  LocalDate targetDate,
                                  boolean done) {

        int i1 = id.isEmpty() ? listToDo.size()+1 : Integer.valueOf(id);
        boolean addedorNot = listToDo.add(new Todo(  i1 , username,description,creationDate,targetDate, done));
        l1.info("insertingg(insert_todo).... given data T/F ==" + addedorNot);
        return  listToDo;
    }
<%@ taglib prefix="test1" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>


<html>
    <head>
        <link href="\webjars\bootstrap\5.1.3\css\bootstrap.min.css" rel="stylesheet">
        <title> Add : Todo    </title>
    </head>
    <body>
            <div class="container">
            

            <form:form method="post" modelAttribute="todooo">
                <p><label>id : </label>
                    <form:input type="text" path="id" required="required"   />

                <p><label>username : </label>
                    <form:input type="text" path="username" required="required"    />

                <p><label>description : </label>
                    <form:input type="text" path="description" required="required"   />

                <p><label>creationDate : </label>
                    <form:input type="text" path="creationDate" required="required"    />
                    
                <p><label>targetDate : </label>
                    <form:input type="text" path="targetDate" required="required"    />
                    <form:errors path="targetDate"   />
                    
                <p><label>done : </label>
                    <form:input type="text" path="done" required="required"    />

                <p><input type="submit" value=" + "  class="btn btn-success"> </input>
            </form:form>

            <p>
                Hint1:
            <p>
                Hint2:
<p><p>

        </div>
        <script src="\webjars\bootstrap\5.1.3\js\bootstrap.min.js"> </script>
        <script src="\webjars\jquery\3.6.0\jquery.min.js"> </script>
    </body>
    <html>
package springboot.ToDo.Model;


import jakarta.validation.constraints.*;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.lang.NonNull;

import java.time.LocalDate;
import java.util.Date;

public class Todo {

    private int id;
    private String username;
    private String description;
    private LocalDate creationDate;
    @Future(message ="targetDate -->  ALLOWED to enter only FUTURE dates " )
    private LocalDate targetDate;
    private boolean done;



    public LocalDate getCreationDate() {
        return creationDate;
    }

    public void setCreationDate(LocalDate creationDate) {
        this.creationDate = creationDate;
    }

    public Todo(int id, String username, String description, LocalDate creationDate , LocalDate targetDate, boolean done ) {
        this.id = id;
        this.username = username;
        this.description = description;
        this.creationDate =creationDate;
        this.targetDate = targetDate;
        this.done = done;
    }

    public int getId() {
        return id;
    }

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

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public LocalDate getTargetDate() {
        return targetDate;
    }

    public void setTargetDate(LocalDate targetDate) {
        this.targetDate = targetDate;
    }

    public boolean getDone() {
        return done;
    }

    public void setDone(boolean done) {
        this.done = done;
    }

    @Override
    public String toString() {
        return "ToDo{" +
                "id=" + id +
                ", username='" + username +
                ", description='" + description +
                ", targetDate=" + targetDate +
                ", creationDate=" + creationDate +
                ", done=" + done
                '}';
    }
}

Tried to debug the code and the error is triggered only when validation + two way binding are added. Without validation + two way binding tags, everything works fine.


UPDATE:

PROBLEM is solved now by just adding @Valid @ModelAttribute("todooo")

Thanks to ...

  1. Roman C'

  2. https://codingexplained.com/coding/java/spring-framework/neither-bindingresult-nor-plain-target-object-available-as-request-attribute#comment-295414



Solution

  • The error comes to you application because you didn't specify an attribute of the model passed to the POST method. Add @ModelAttribute("todooo") to the method parameter:

    public String post_insert_data(ModelMap modelMap, @Valid @ModelAttribute("todooo") Todo todooo, BindingResult bindingResult){