java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'User' available as request attribute with root cause [duplicate] - spring

This is meant to be an extensive canonical question & answer post for these types of questions.
I'm trying to write a Spring MVC web application where users can add movie names to an in-memory collection. It's configured like so
public class Application extends AbstractAnnotationConfigDispatcherServletInitializer {
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] {};
}
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { SpringServletConfig.class };
}
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
and
#Configuration
#ComponentScan("com.example")
public class SpringServletConfig extends WebMvcConfigurationSupport {
#Bean
public InternalResourceViewResolver resolver() {
InternalResourceViewResolver vr = new InternalResourceViewResolver();
vr.setPrefix("WEB-INF/jsps/");
vr.setSuffix(".jsp");
return vr;
}
}
There's a single #Controller class in the com.example package
#Controller
public class MovieController {
private final CopyOnWriteArrayList<Movie> movies = new CopyOnWriteArrayList<>();
#RequestMapping(path = "/movies", method = RequestMethod.GET)
public String homePage(Model model) {
model.addAttribute("movies", movies);
return "index";
}
#RequestMapping(path = "/movies", method = RequestMethod.POST)
public String upload(#ModelAttribute("movie") Movie movie, BindingResult errors) {
if (!errors.hasErrors()) {
movies.add(movie);
}
return "redirect:/movies";
}
public static class Movie {
private String filmName;
public String getFilmName() {
return filmName;
}
public void setFilmName(String filmName) {
this.filmName = filmName;
}
}
}
WEB-INF/jsps/index.jsp contains
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Movies</title>
</head>
<body>
Current Movies:
<c:forEach items="${movies}" var="movieItem">
<ul>
<li>${movieItem.filmName}</li>
</ul>
</c:forEach>
<form:form>
<div>Movie name:</div>
<form:input path="filmName" type="text" id="name" />
<input type="submit" value="Upload">
</form:form>
</body>
</html>
The application is configured with context path /Example. When I send a GET request to
http://localhost:8080/Example/movies
the request fails, Spring MVC responds with a 500 status code, and reports the following exception and stack trace
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'command' available as request attribute
org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:144)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getBindStatus(AbstractDataBoundFormElementTag.java:168)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getPropertyPath(AbstractDataBoundFormElementTag.java:188)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getName(AbstractDataBoundFormElementTag.java:154)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.writeDefaultAttributes(AbstractDataBoundFormElementTag.java:117)
org.springframework.web.servlet.tags.form.AbstractHtmlElementTag.writeDefaultAttributes(AbstractHtmlElementTag.java:422)
org.springframework.web.servlet.tags.form.InputTag.writeTagContent(InputTag.java:142)
org.springframework.web.servlet.tags.form.AbstractFormTag.doStartTagInternal(AbstractFormTag.java:84)
org.springframework.web.servlet.tags.RequestContextAwareTag.doStartTag(RequestContextAwareTag.java:80)
org.apache.jsp.WEB_002dINF.jsps.index_jsp._jspx_meth_form_005finput_005f0(index_jsp.java:267)
org.apache.jsp.WEB_002dINF.jsps.index_jsp._jspx_meth_form_005fform_005f0(index_jsp.java:227)
org.apache.jsp.WEB_002dINF.jsps.index_jsp._jspService(index_jsp.java:142)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:438)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:396)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:340)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:168)
org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:303)
org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1257)
org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1037)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:980)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
I expected the JSP to generate an HTML <form> with a single text input, for a Movie name, and a submit button, that I can use to send a POST request with a new Movie. Why does the JSP servlet instead fail to render Spring's <form:form> tag?

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:
Send HTTP GET request
DispatcherServlet selects #RequestMapping method to handle request
Handler method generates some model attributes and returns view name
DispatcherServlet adds model attributes to HttpServletRequest and forwards request to JSP corresponding to view name
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.

I tried to migrate my application to Spring5 and noticed the same issue. It was caused by the moment that the 'commandName' attribute is not supported anymore and I had to use 'modelAttribute' instead.

To make things simple with the form tag just add a "commandName" which is a horrible name for what it is actually looking for...it wants the object you named in the MdelAttribute annotation. So in this case commandName="movie".
That'll save you reading long winded explanations friend.

I had this error on a screen with multiple forms that do a search. Each form posts to its own controller method with results shown on same screen.
Problem: I missed adding the other two forms as model attributes in each controller method causing that error when screen renders with results.
Form1 -> bound to Bean1 (bean1) -> Posting to /action1
Form2 -> bound to Bean2 (bean2) -> Posting to /action2
Form3 -> bound to Bean3 (bean2) -> Posting to /action3
#PostMapping
public String blah(#ModelAttribute("bean1") Bean1 bean, Model model){
// do something with bean object
// do not miss adding other 2 beans as model attributes like below.
model.addAttribute("bean2", new Bean2());
model.addAttribute("bean3", new Bean3());
return "screen";
}
#PostMapping
public String blahBlah(#ModelAttribute("bean2") Bean2 bean, Model model){
// do something with bean object
// do not miss adding other 2 beans as model attributes like below.
model.addAttribute("bean1", new Bean1());
model.addAttribute("bean3", new Bean3());
return "screen";
}
#PostMapping
public String blahBlahBlah(#ModelAttribute("bean3") Bean3 bean, Model model){
// do something with bean object
// do not miss adding other 2 beans as model attributes like below.
model.addAttribute("bean1", new Bean1());
model.addAttribute("bean2", new Bean2());
return "screen";
}

In my case, it worked by adding modelAttribute="movie" to the form tag, and prepending the model name to the attribute, something like <form:input path="filmName" type="text" id="movie.name" />

Updating from Spring version 3 to Spring version 5, produces the same error. All answers were satisfied already in my code. Adding the annotation #ControllerAdvice solved the problem for me.

If your Model object is correctly being passed to the GET API call but still have this error, you may look at the html or jsp page also to check whether correct variables names are provided and tags are used correctly. In my case, I forgot to include the objects under the closing <form> tag.

Related

Spring form commandName = session attribute

I have many pages with the same form where I bind my object using commandName. I try to put the object to session with name "myObject" and use it for form (commandName = "myObject"). But system throws exception (Neither BindingResult nor plain target object for bean name "myObject").
How can I bind the object to session for any controllers and requests?
That error is typical when your use a form:form tag that targets a command object that is not available in the request.
A good approach is to combine #ModelAttribute annotated method with #SessionAttributes on a Controller that intially forwards to the view that contains the form, something like
#Controller
#SessionAttributes("myObject")
public class FormController {
#ModelAttribute("myObject")
public MyObject createMyObjectBean() {
return new MyObject();
}
...
}
The initally createMyObjectBean will be called with whatever is the first request to the controller methods, but it won't be called on subsequent request as the myObject value will come from session due to #SessionAttributes
just note that for this approach to work, you must have a controller that forwards to the view that contains your form

In MVC how is the data passed from JSP to Controller?

I'm following the Spring MVC tutorial here: http://www.tutorialspoint.com/spring/spring_mvc_form_handling_example.htm
and I'm not getting the logic how is the data passed from JSP to Controller.
I think I understand how the data is passed from the Controller to the JSP, but after the user has edited the form on the JSP how is the data passed to the Controller?
In the controller:
public String addStudent(#ModelAttribute("SpringWeb")Student student, ModelMap model)
question:
How the controller knows that from the form on the jsp Student class instance student with name, age and id are passed?
I have this example working. I have altered the example to display a list of students, but I am not able to get the list from JSP to Controller:
#RequestMapping(value = "/student", method = RequestMethod.POST)
public ModelAndView studentSave(#ModelAttribute("listOfStudents") ArrayList<Student> listOfStudents,ModelMap model)
{
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
StudentJDBCTemplate studentJDBCTemplate = (StudentJDBCTemplate) context.getBean("studentJDBCTemplate");
System.out.println("Size of listOfStudents is = " + listOfStudents.size());
...
listOfStudents.size() returns 0.
question: what am i missing here, why I can't get the list from the form on the jsp?
question: How the controller knows that from the form on the jsp
Student class instance student with name, age and id are passed?
When you submit the form you are making an HTTP (typically, POST) request to a given URL. This POST request will contain the values in
the form as request parameters. If you were not using any web framework (e.g. Spring MVC) then you would typically work directly with the Servlet API
to extract and work with these values, particularly the HttpServletRequest object.
http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html
You can try this is your application by adding the following (the Spring MVC framework will automatically pass in the request).
public String addStudent(#ModelAttribute Student student, HttpServletRequest request){
for(String key : request.getParameterMap().keySet()){
System.out.println(key + "=" + request.getParameterMap().get(key);
}
}
Now, regardless of the framework you are using the underlying mechanism does not change, the parameters are still sent in the POST request as simple Strings.
The framework however essentially adds an abstraction layer on top of this to prevent you having to write boilerplate to extract and manually work with these
parameters. So, rather than having to do the following:
public String addStudent(HttpServletRequest request){
Student student = new Student();
student.setId(Integer.parseInt(request.getParameter("id"));
student.setName(request.getParameter("name"));
....
}
you let the framework take care of it.
public String addStudent(#ModelAttribute Student student){
}
The #ModelAttribute tells the framework you want the submitted parameters to be bound to a Student instance. On submit, the framework will create a new Student
instance and, by means of reflection, (http://docs.oracle.com/javase/tutorial/reflect/) set the various fields to the corresponding HTTP params.
As for the 2nd part of your question there are numerous examples of how to bind to a Collection. See below for example:
http://viralpatel.net/blogs/spring-mvc-multi-row-submit-java-list/
Generally 'work' is done in the controller, and the results are passed to the JSP simply for display. The JSP renders to the user's browser over HTTP and then the user modifies the page and posts back to the controller.
If you're doing 'work' in the JSP that needs to be passed back to the controller before the page is sent to the user, then you should consider finding a way of doing all that in the controller.
Having said this. The model that you pass to the JSP doesn't have to contain simple objects. You can pass to the JSP an object that has methods on it that performs processing. Then in the JSP you simply call one of the methods on that object.
the controller and jsp are linked together by #ModelAttribute.
example if i want to add a new student i would first link the corresponding jsp page with the student database. like
//setup add new student form
#RequestMapping(value = "/add", method = RequestMethod.GET)
public String setStudentForm(#ModelAttribute("newStudent") Student newStudent){
return "addstudent";
}
this will set up my jsp page. In jsp page i have already declared the colums like firstname, lastname which are linked with my student model.
<form:form modelAttribute="newStudent" class="form-horizontal">
<form:input id="firstName" path="firstName" type="text"/>
<form:input id="lastName" path="lastName" type="text"/>
<input type="submit" id="btnAdd" value ="add"/>
</form>
Like this i created the ling. Now when i press submit button if will land a post request and thus following method in controller will be executed.
#RequestMapping(value = "/add", method = RequestMethod.POST)
public String processStudentForm(Model model, #ModelAttribute("newStudent") #Valid Student newStudent, BindingResult result ){
newStudent.setFirstName("gurpreet");
if(result.hasErrors()){
return "addstudent";
}
studentService.add(newStudent);
model.addAttribute("message", "Added successfully");
return "redirect:/students";
}
I can also make changes in the data like i did newStudent.setFirstName("gurpreet"); before saving the object through studentService
the #RequestMapping url is same but method has changed to POST from GET as submit button have POST submission.
(#ModelAttribute("newStudent") Student newStudent)
associates our view, Model and controller alltogether.

Spring: #ModelAttribute VS #RequestBody

Please correct me if I am wrong.
Both can be used for Data Binding.
The question is when to use #ModelAttribute?
#RequestMapping(value="/owners/{ownerId}/pets/{petId}/edit", method = RequestMethod.POST)
public String processSubmit(#ModelAttribute Pet pet) { }
In addition, when to use #RequestBody?
#RequestMapping(value = "/user/savecontact", method = RequestMethod.POST
public String saveContact(#RequestBody Contact contact){ }
According to my understanding both serves the similar purpose.
Thanks!!
The simplest way for my understanding is, the #ModelAttribute will take a query string. so, all the data are being pass to the server through the url.
As for #RequestBody, all the data will be pass to the server through a full JSON body.
#ModelAttribute is used for binding data from request param (in key value pairs),
but #RequestBody is used for binding data from whole body of the request like POST,PUT.. request types which contains other format like json, xml.
If you want to do file upload, you have to use #ModelAttribute. With #RequestBody, it's not possible. Sample code
#RestController
#RequestMapping(ProductController.BASE_URL)
public class ProductController {
public static final String BASE_URL = "/api/v1/products";
private ProductService productService;
public ProductController(ProductService productService) {
this.productService = productService;
}
#PostMapping
#ResponseStatus(HttpStatus.CREATED)
public ProductDTO createProduct(#Valid #ModelAttribute ProductInput productInput) {
return productService.createProduct(productInput);
}
}
ProductInput class
#Data
public class ProductInput {
#NotEmpty(message = "Please provide a name")
#Size(min = 2, max = 250, message = "Product name should be minimum 2 character and maximum 250 character")
private String name;
#NotEmpty(message = "Please provide a product description")
#Size(min = 2, max = 5000, message = "Product description should be minimum 2 character and maximum 5000 character")
private String details;
#Min(value = 0, message = "Price should not be negative")
private float price;
#Size(min = 1, max = 10, message = "Product should have minimum 1 image and maximum 10 images")
private Set<MultipartFile> images;
}
I find that #RequestBody (also annotating a class as #RestController) is better for AJAX requests where you have complete control over the contents of the request being issued and the contents are sent as either XML or JSON (because of Jackson). This allows the contents to easily create a model object. Conversely, #ModelAttribute seems to be better suited to forms where there is a "command" object backing a form (which may not necessarily be a model object).
You can directly access your "pet" object in view layer, if you use ModelAttribute annotation. Also, you can instantiate this object in a method on your controller to put your model. see this.
ModelAttribute gives you a chance to use this object partial, but with RequestBody, you get all body of request.
I think #ModelAttribute and #RequestBody both are having same use, only difference
is #ModelAttribute use for normal spring MVC and #RequestBody use for REST web service. It is #PathVariable and #PathParam. But in in both the cases we can mix it. we can use #PathVariable in REST and vice versa.
With #ModelAttribute, you pass data in URL params and with #RequestBody you pass it as JSON body. If you're making a REST API then it's better to use #RequestBody. Over most youtube tutorials you might find use of #ModelAttribute - That's simply because they might be demonstrating concepts regarding Spring MVC and are using URL's to pass data.
We need to have the following jsp tag to data bind your entity to the jsp form fields:
The form is from the spring tag library:
The following is the not the full html, but I hope you can relate your self:
<%#taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<form:form action="save" method="post" modelAttribute="patient">
<table>
<tr>
<td>Name</td>
<td>
<form:input path="patient.patient_name" /> <br />
</td>
</tr>
<tr>
<td>Phone</td>
<td>
<form:input path="patient.phone_number" /> <br />
</td>
</tr>
<tr>
<td colspan="2"><button type="submit">Submit</button></td>
</tr>
</table>
</form:form>
The form has to be processed twice , once before rendering the form, during which we need to give the appropriate bean instantiation for the property value modelAttribute="patient".
For this the controller class(at the class defintion level) you need to have #RequestMapping annotation.
You need to have the handler method parameters as follows
#GetMapping("logincreate")
public String handleLoginCreate(#ModelAttribute("login") Login login, Model model)
{
System.out.println(" Inside handleLoginCreate ");
model.addAttribute("login",login);
return "logincreate";
}
Spring will scan all handler methods #ModelAttribute and instantiate it with default constructor of Login class, and call all of its getters and setters (for the jsp binding from form to the "login"). In case of missing any of the following the jsp will not be shown, various exceptions are thrown
getters/setters
default constructor
model.addAttribute("login",login);
class level #RequestMapping
method parameter level #ModelAttribute
Also, the handler method of action in the jsp, the in the above form action="save", also the handler method might look like this:
#PostMapping("save")
public String saveLoginDetails(#ModelAttribute("login") Login login, Model model) {
//write codee to insert record into DB
System.out.println(" Inside save login details ");
System.out.println("The login object is " + login.toString());
System.out.println("The model object contains the login attribute"+ model.getAttribute("login"));
loginService.saveLogin(login);
return "welcome";
}
Important learning is:
Before form is launched, spring should have appropriate annotation to indicate the backing bean of the form, in the above example the "backing bean" or "binding object" is Login login with appropriate handler method's parameter annotation #ModelAttribute("login") Login login

Data binding without using spring taglib

My html is built without using the spring taglib and now I'd like to bind the parameters of the form to a object in my controller.
Currently my form looks like this
<form>
<input type="text" name="frAccUserMgmt.userName"/>
<input type="password" name="frAccUserMgmt.userPwd"/>
</form>
The relevant part of my object is
Class FrAccUserMgmt {
private String userName;
private Strint userPwd;
// getter and setter
}
My controller is
#RequestMapping("login")
Public ModelAndView doLogin(FrAccUserMgmt frAccUserMgmt) {
//code
}
How do I go about binding it. Currently the binding doesn't happen. I just get an empty object in my code.
You could try including the BindingResult class in the method signature and then see if there are any binding errors:
#RequestMapping("login")
Public ModelAndView doLogin(FrAccUserMgmt frAccUserMgmt, BindingResult result) {
if (result.hasErrors()) {
logger.warn("BindingResult errors: " + result.toString());
}
//code
}
Remove the frAccUserMgmt part from the form field names. Spring will automatically find the command object to bind the request parameters based on the getters and setters defined in the command object.
This can also be done by adding the #ModelAttribute for the parameter bean that should be populated with the request parameters.
As per spring docs
http://docs.spring.io/spring/docs/3.1.x/spring-framework-reference/html/mvc.html#mvc-ann-modelattrib-method-args
(16.3.3.8 Using #ModelAttribute on a method argument)
An #ModelAttribute on a method argument indicates the argument should be retrieved from the model. If not present in the model, the argument should be instantiated first and then added to the model. Once present in the model, the argument's fields should be populated from all request parameters that have matching names. This is known as data binding in Spring MVC, a very useful mechanism that saves you from having to parse each form field individually.

Passing a List from Action class to jsp and From JSP to action class in struts2

I have a requirement where i am using Struts2 as well as Jqgrid in JSP.
As per my requirement i am getting a list from different action class through interceptor.
I have to pass the list to JSP and from the Jgrid url back to respective action class.
When i am using request.setAttribute and passing the same value as parameter for
jqgrid action class url its working fine
[E.g showExcelGrid.action?LIST='+"<%=request.getAttribute("LIST")%>" but when list is large its not working properly.
Please suggest some ideas.
Thanks
I am not sure how JqGrid work but below describe the way value flow both way
To send List/Map or any other collection backed object from your action class to JSP all you need to create a list property in your action class and provide its getter and setters for this
Sample Action Class
public class SampleAction extends ActionSupport{
private List<String> listForJspPage;
//getter and setter for this list property
public String execute() throws Exception{
listForJspPage=new ArrayList<String>();
listForJspPage=fill this list with values
return SUCCESS;
}
}
with above code when your action will get executed you have listForJspPage in value stack and can be accessed using OGNL
Sample JSP
<s:iterator value="listForJspPage">
// do what ever you want to fo
</s:itertor>
here value="listForJspPage" will be interpreted by S2 as getListForJspPage() in your action class to fetch the values.
For sending the value back to action class we can make sure of the setter method with a little help from OGNL like
<s:iterator value="listForJspPage">
<s:textfield name="listForJspPage['%{id}'].value" value="%{value}" />
</s:itertor>
In this we iterate over the listForJspPage List. On the textfield tag we set the name to "listForJspPage['%{id}'].value", this would result in something that looks like "listForJspPage['1'].value". which further can be seen as
getListForJsppage().get(index).setvalue(out given value);
I know this late, but I found this one today which works.
You can pass the list from one action class to another via jsp using the s:select tag of struts2 as follows:
List<String> formList //getter and setter should be there in both the action classes
<div id="divList" style="display: none;">
<s:select list="formlist" multiple="true" id="selectedList" name="formListList"></s:select>
</div>

Resources