What Causes "Java.Lang.Illegalstateexception: Neither Bindingresult Nor Plain Target Object For Bean Name 'Command' Available as Request Attribute"

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

In the controller, you need to add the login object as an attribute of the model:

model.addAttribute("login", new Login());

Like this:

@RequestMapping(value = "/", method = RequestMethod.GET) 
public String displayLogin(Model model) {
model.addAttribute("login", new Login());
return "login";
}

Getting Neither BindingResult nor plain target object for bean name 'bean name' available as request attribute when looping

I was able to solve the issue by adding the following method to My controller:

    @ModelAttribute
Color setupForm () {
return new Color();
}

This is old! Not a real solution.
My solution ended up editing index.html to the following:

        <div class="col-sm-3" th:each="type,iter : ${T(com.piinfo.service.Type).values()}">
<form class="card form-color"
method="POST" action="#"
th:action="@{/}"
>
<div class="card-header text-center h2" th:text="${type.displayName}"></div>
<div class="card-body">
<div class="form-group">
<label th:text="${type.displayName}+': '" th:for="'color'+${iter.count}"></label>
<input class="form-control" type=color th:id="'color'+${iter.count}" name="color"
th:value="${colors.get(type)}"/>
</div>
<div class="form-group">
<label th:text="'Passwort: '" th:for="'pass'+${iter.count}"></label>
<input class="form-control" type=password name="pass" th:id="'pass'+${iter.count}"/>
</div>
<div class="form-group">
<input type="hidden" th:value="${type}" name="type" th:id="'type'+${iter.count}"/>
<input class="form-control" type="submit">
</div>
</div>
</form>
</div>

The original Question didn't work, because aparrently you can't use th:object on something, that came from th:each.

What causes java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'command' available as request attribute?

You're trying to use Spring MVC's form tag.

This tag renders an HTML form tag and exposes a binding path to
inner tags for binding. It puts the command object in the PageContext
so that the command object can be accessed by inner tags. [..]

Let’s assume we have a domain object called User. It is a JavaBean
with properties such as firstName and lastName. We will use it as the
form backing object of our form controller which returns form.jsp.

In other words, Spring MVC will extract a command object and use its type as a blueprint for binding path expressions for form's inner tags, like input or checkbox, to render an HTML form element.

This command object is also called a model attribute and its name is specified in the form tag's modelAttribute or commandName attributes. You've omitted it in your JSP

<form:form> 

You could've specified a name explicitly. Both of these are equivalent.

<form:form modelAttribute="some-example-name">
<form:form commandName="some-example-name">

NOTE: Spring 5 has removed the commandName attribute, see the upgrade notes, here.

The default attribute name is command (what you see in error message). A model attribute is an object, typically a POJO or collection of POJOs, that your application supplies to the Spring MVC stack and which the Spring MVC stack exposes to your view (ie. the M to the V in MVC).

Spring MVC collects all model attributes in a ModelMap (they all have names) and, in the case of JSPs, transfers them to the HttpServletRequest attributes, where JSP tags and EL expressions have access to them.

In your example, your @Controller handler method which handles a GET to the path /movies adds a single model attribute

model.addAttribute("movies", movies); // not named 'command'

and then forwards to the index.jsp. This JSP then tries to render

<form:form>
...
<form:input path="name" type="text" id="name" />
...
</form:form>

While rendering this, FormTag (in reality, the InputTag) tries to find a model attribute named command (the default attribute name) so that it can produce an HTML <input> element with a name attribute constructed from the path expression and the corresponding property value, ie. the result of Movie#getFilmName().

Since it cannot find it, it throws the exception you see

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

The JSP engine catches it and responds with a 500 status code. If you want to take advantage of a Movie POJO to simply construct your form correctly, you can add a model attribute explicitly with

model.addAttribute("movie", new Movie());

or have Spring MVC create and add one for you (must have an accessible parameterless constructor)

@RequestMapping(path = "/movies", method = RequestMethod.GET)
public String homePage(@ModelAttribute("command") Movie movie, Model model) {...}

Alternatively, include a @ModelAttribute annotated method in your @Controller class

@ModelAttribute("command")
public Movie defaultInstance() {
Movie movie = new Movie();
movie.setFilmName("Rocky II");
return movie;
}

Note that Spring MVC will call this method and implicitly add the object returned to its model attributes for each request handled by the enclosing @Controller.

You may have guessed from this description that Spring's form tag is more suited for rendering an HTML <form> from an existing object, with actual values. If you want to simply create a blank <form>, it may be more appropriate to construct it yourself and not rely on any model attributes.

<form method="post" action="${pageContext.request.contextPath}/movies">
<input name="filmName" type="text" />
<input type="submit" value="Upload" />
</form>

On the receiving side, your POST handler method, will still be able to extract the filmName input value and use it to initialize a Movie object.

Common Errors

As we've seen, FormTag looks for a model attribute named command by default or with the name specified in either modelAttribute or commandName. Make sure you're using the right name.

ModelMap has a addAttribute(Object) method which adds

the supplied attribute to this Map using a generated name.

where the general convention is to

return the uncapitalized short name of the [attribute's] Class, according to
JavaBeans property naming rules: So, com.myapp.Product becomes
product; com.myapp.MyProduct becomes myProduct; com.myapp.UKProduct
becomes UKProduct

If you're using this (or a similar) method or if you're using one of the @RequestMapping supported return types that represents a model attribute, make sure the generated name is what you expect.

Another common error is to bypass your @Controller method altogether. A typical Spring MVC application follows this pattern:

  1. Send HTTP GET request
  2. DispatcherServlet selects @RequestMapping method to handle request
  3. Handler method generates some model attributes and returns view name
  4. DispatcherServlet adds model attributes to HttpServletRequest and forwards request to JSP corresponding to view name
  5. JSP renders response

If, by some misconfiguration, you skip the @RequestMapping method altogether, the attributes will not have been added. This can happen

  • if your HTTP request URI accesses your JSP resources directly, eg. because they are accessible, ie. outside WEB-INF, or
  • if the welcome-list of your web.xml contains your JSP resource, the Servlet container will render it directly, bypassing the Spring MVC stack entirely

One way or another, you want your @Controller to be invoked so that the model attributes are added appropriately.

What does BindingResult have to do with this?

A BindingResult is a container for initialization or validation of model attributes. The Spring MVC documentation states

The Errors or BindingResult parameters have to follow the model object
that is being bound immediately as the method signature might have
more than one model object and Spring will create a separate
BindingResult instance for each of them [...]

In other words, if you want to use BindingResult, it has to follow the corresponding model attribute parameter in a @RequestMapping method

@RequestMapping(path = "/movies", method = RequestMethod.POST)
public String upload(@ModelAttribute("movie") Movie movie, BindingResult errors) {

BindingResult objects are also considered model attributes. Spring MVC uses a simple naming convention to manage them, making it easy to find a corresponding regular model attribute. Since the BindingResult contains more data about the model attribute (eg. validation errors), the FormTag attempts to bind to it first. However, since they go hand in hand, it's unlikely one will exist without the other.

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

You forgot to add BindingResult after your @ModelAttribute :

@RequestMapping(value="/person", method=RequestMethod.POST)
public String contactSubmit(@ModelAttribute Person person, BindingResult bindingResult, Model model) {
if (bindingResult.hasErrors()) {
//errors processing
}
model.addAttribute("person", person);
return "result";
}

I'm already have answered to question like this :

  • html form validation using thymeleaf not working spring boot

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

If you use modelAttribute="watchlist" on your jsp, you must return the Model with attribute watchlist as following

 @GetMapping("/")
String index(Model m) {
// you should have this so that modelAttribute="watchlist" on jsp renders
m.addAttribute("watchlist", new Watchlist());

return "myjspform";
}

Here's working code:

package soquestion64416269;

import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}

@Controller
@RequiredArgsConstructor
class Ctrl {

@GetMapping("/")
String index(Model m) {
m.addAttribute("msg", "Enter symbol and click Add");
m.addAttribute("watchlist", new Watchlist());

return "myjspform";
}

@PostMapping(value = "/AddSymbolToWatchlist")
public String addSymbolToWatchlist(@ModelAttribute("watchlist") Watchlist watchlist, Model m) {
m.addAttribute("msg", watchlist.getSymbol() + " was submitted. Now enter new symbol and click Add");
m.addAttribute("watchlist", new Watchlist());

return "myjspform";
}
}

@Data
class Watchlist {
String symbol;
}

myjspform.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html lang="en">
<body>

<h2>Message: ${msg}</h2>

<form:form method="POST" action="/AddSymbolToWatchlist" modelAttribute="watchlist">
<form:label path="symbol">Enter Symbol:</form:label>
<form:input path="symbol"/><br><br>
<form:button>Add</form:button>
</form:form>

</body>
</html>

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

Annotate your controller handler method's parameter with @ModelAttribute("subscription"). By default, without the value given, Spring will generate an attribute name based on the type of the parameter. Thus MyMainObject will become myMainObject.

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

You are missing adding Referrals object to model.

    @RequestMapping(value="/saveReferral", method=RequestMethod.POST)
public ModelAndView save(@ModelAttribute("saveReferral") Referrals referral){
ModelAndView model=new ModelAndView("referralPage");
model.addAttribute("categoryOptions",new Referrals()); //or referral
return model;
}

Exception is occuring because of <f:select path="categoryOptions">,you have mentioned categoryOptions in path but no where you are returning to this jsp with categoryOptions.

Update : So this says whenever you are loading referral jsp, you have to load with categoryOptions bean

And in below lines list is added to model using model.addObject() but path variable categoryOptions is missing. So after the line model.addObject("list", list); add model.addAttribute("categoryOptions", new Referrals());

<f:select path="categoryOptions">
<f:options items="${list}"/>
</f:select>

SpringMVC - Java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name

In layman's terms this is how Spring MVC works -

  • Create a bean (generally in GET handler) to which you want to bind your data. (This bean is referred to as command object)

  • Put the command object in model

  • Return a view name. (Spring will resolve the view and send the model to the view)

  • Bind data (user input) to the command object

  • Retrieve the command object with data in the controller (POST or other alike handlers)


Solution to Your Problem:

You are calling model.clear(); in your GET handler. So, in the view layer, the model is empty and no target bean (i.e. command object) is available to bind data to.

So remove the mode.clear(); call.

NOTE

One other common mistake is to use different names for the key of the command object in the model and in the value of commandName of <form:form/>.

i.e., If you put the command object in model as model.put("fooBar", someFooBar);, in view you need to do <form:form commandName="fooBar" .../>


Further Reading

  • Annotated Controllers section in Spring Framework Reference


Related Topics



Leave a reply



Submit