Can I separate a spring form? - spring-mvc

I am using tiles, Spring MVC, Spring form tag. I want to make a form that step by step. When click a button, show more inputs from another tiles definition. But throw a exception can not find "Neither BindingResult nor plain target object for bean name " , It looks the "more inputs" can not get bindle object from previous request, is it right?
Source code:
<form:form action="/saveTicker.do" commandName="ticker" modelAttribute="ticker" method="post">
...
<form:input path="name" id="name"/>
Confirm
<div class="row" id="filelist">
</div>
</form>
js
var confirmTicker=function(){
var ticker=$('input:text').val();
$.get("/confirmTicker.do",{ticker:ticker}).success(function(data){
$('#filelist').html(data);
});
}
want to import another file
<table class="table ">
<c:forEach var="f" items="${fileList}">
<tr>
<td>
<form:checkbox path="files" value="${f}"></form:checkbox>
</td>
</tr>
</c:forEach>
</table>
The error is
Neither BindingResult nor plain target object for bean name 'files' available as request attribute

If I am reading this correct, what you want is a "wizard" form where the user is passed from one form to the next as a series of steps. First, I believe Spring Web Flow does this out of the box, but, if like me, you cannot use Spring Web Flow you can do this manually.
First, you need a Form Bean (read Command object) that has all the possible inputs from all the forms.
Next, you will either have one Controller method that accepts your Form Bean and returns the proper step (this is what I did), or you can have multiple methods...it doesn't matter. You will use the #ModelAttribute annotation on the handler method to bind the Form Bean to the view form. Also, #SessionAttributes annotation at the top of the controller to set the Form Bean as a session attribute. Make sure the name of the #ModelAttribute, #SessionAttribute, and the view all correspond to the same attribute name.
Last, create multiple views, each with the same , but each with only the pieces you want to set on the FormBean at that point. You cannot use JSR 303, or at least I don't know how you can, since you can't have validation done between steps. You will have to handle validation at the end on your own.

Related

Pass parameter in request while using spring vmc form

I am using spring mvc form to submit request. I have a hidden variable which i want to pass to the controller. The hidden variable path is using a property which present in the model attribute object. Now I want to pass this hidden variable to the controller. For this one approach is to have the this variable in the model which curremtly is present. But I dont want to put this hidden variable in the model vo object. I just want to pass this hidden field as a request parameter to the controller. Is there any way to do that? If I use html input field type=hidden, will work ?
Please let me know. Below is the code for this. The value of the hi9dden field i am setting from javascript and doing the form submit.
JSP file
<form:form id="form" modelAttribute="customerRelationshipBean">
<form:hidden path="customerSearchBean.action" /> </form>
JS file
document.getElementById("customerSearchBean.action").value='addCustomer';
document.getElementById("form").action = '/gcldw-web/customerSearch' ;
document.getElementById("form").method='POST';
document.getElementById("form").submit();
As soon as you use's spring tags hidden element with a path attribute you establish an associatation with a model bean, and the value ends up in the model
Instead, you can simply add a plain input hidden element, e.g.
<input type="hidden" id="secretValue" name="secretValue" value="" />
place the value to that element (via your js code) and add a suitable #RequestParam argument to your handle method e.g.
public String processSubmit(#ModelAttribute("customerSearchBean") CustomerSearchBean customerSearchBean, BindingResult result,
#RequestParam String secretValue) {

Retrieve the form method from Spring-mvc's RequestDataValueProcessor

I want to retrieve the http method of the spring's <form:form> tag from inside a RequestDataValueProcessor in order to generate different hidden fields depending on it. I have access to the form action, but it seems there is no way to retrieve the http method of the form.
I am using Spring 3.2.
Edit: I have added an example.
Imagine the form below being retrieved with GET. What I want is to read the method parameter of the <form:form> tag in order to add a hidden field depending on the method. Obviously, I can't use request.getMethod() because this would return the method of the original request, not the method of the form being processed by RequestDataValueProcessor.
<form:form action="/foo/bar" method="post" modelAttribute="${modelAttribute}" >
<form:input path="myField" />
<input id="proceed" type="submit" value="Save" />
</form:form>
It seems that there is a pending issue to allow access to the form method in RequestDataValueProcessor.
This is the issue: https://jira.springsource.org/browse/SPR-10041
Definitely an open issue on Spring, but doesn't look like its going to be addressed soon.
Here is what you can do.. its not straight forward though, so weigh the cost vs benefit before you start :)
RequestDataValueProcessor will not work for you, you already know that. The way the FormTag is programmed, it calls specific methods (hooks) from the value processor at specific times, during the execution of the form tag.
You can create your own custom form tag, which will do everything Spring's form tag does, either by composition or inheritence. But in addition, you can call your own Value Processor esque class when the form method is detected by the tag. This class can then decide what additional steps you want to take and you can then use the regular ValueProcessor to add hidden fields as you see fit.
These questions talk about how to extend spring's tags, by creating your own: SpringMVC Custom Form Tags and Create a custom tag library which extends the Spring tag library.
Also look at the source code of the FormTag https://github.com/SpringSource/spring-framework/blob/master/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/form/FormTag.java. See how the protected processAction method calls the value processor hook, you'll have to do something similar, but in the getMethod method.
Hope this answer makes sense, let me know if you want me to re-phrase or elaborate any point.
Happy programming!
A little more information would be helpful such as what version of Spring you are using.
From the Spring 3.2 API Documentation for RequestDataValueProcessor, I see that there are four (4) methods that you could possibly be working within. In each of those, you have access to the HttpServletRequest.
Accordingly, you have access to whatever HTTP Method the inbound request was made with by calling (link):
request.getMethod()
This should give you exactly what you're looking for.

Default constructor parameter values in ASP.Net MVC?

I’m using MVC3, with the Razor syntax, and am going over an example in the Apress book “Pro ASP.Net MVC 3 Framework” (which is very good). In it the author has this bit in a _Layout.cshtml file:
<body>
<div id="header">
#{Html.RenderAction("Summary", "Cart");}
<div class="title">SPORTS STORE</div>
</div>
<div id="categories">
#{ Html.RenderAction("Menu", "Nav"); }
</div>
<div id="content">
#RenderBody()
</div>
</body>
My question has to do with the CartController class. I see that it’s passed a Cart object in its constructor, but the code in the _Layout.cshtml snippet above doesn’t appear to pass one in when RenderAction() is called?
CartController snippet:
public ViewResult Summary(Cart cart) {
return View(cart);
}
When I debug that method a Cart object is in fact passed in, but I don’t see where it’s coming from. This sample code uses Ninject as a dependency injection container but I can’t find any evidence in the configuration that it knows anything about the Cart class. Is there a ‘default value’ mechanism in MVC?
Summary is an action method. It is not a constructor. Therefore, DI doesn't have anything to do with this. Instead, what we are seeing is the behavior of the default model binder. That is to say, the model binder will analyze whatever parameters you declare for your action method and will attempt to populate these arguments with data derived from form or query string parameters and route values.
In your particular scenario, since you are not passing in any route values to your Html.Action call, all it's doing is instantiating the Cart class -- if you inspect it you will presumably see that it's empty (no properties have been set).
However, if you were to pass route values into your Action call, it would populate that object. For example, if Cart contained a property called "Size" of type int, and your action call looked like:
#Html.Action("Summary", "Cart", new { Size = 5 })
Your Cart class would now have its Size property set to 5.
(Note also that it's far cleaner to use the Action method and not the RenderAction method in this case. As you've seen, RenderAction assumes a statement-level call, which requires those ugly enclosing curly braces. Action on the other hand is an expression and returns the actual HTML content inline, and thus can be expressed in a more concise fashion.)
Summary is actually an action method, not a constructor. The data can come from a number of different places:
Route parameters
Query String
Form Variables
Etc.

Spring MVC Data binding error

When submitting a form I get the message:
com.xxx.mvc.reports.ReportController: Data binding errors: 6 {||||||| - |}
The command class inherits from an abstract base class.
When using debugging I can see that the values are set on the command class. I use spring 2.5. Somehwere after the fields are set and between the calling of onSubmit in the controller the error occurs. I use a SimpelFormController. The onSubmit method isn't called so I can't inspect the BindException there.
What does this mean and how can I troubleshoot this?
I barely posted the question and I found the answer:
<form:errors path="pathName"/>
gives me the errors.
If you want to easily see every binding error related to your command bean in the page, put something like:
<spring:bind path="command.*">
<c:forEach items="${status.errorMessages}" var="error">
<font color="red">Error code: <c:out value="${error}"/></font>
<br><br>
</c:forEach>
</spring:bind>
The code is for a bean named "command", as default.

Spring MVC checkbox tag bound to collection expects object but validation expects object.id

In my Spring MVC project I have an update page for Class1 that must display a list of form:checkbox tags that is bound to a collection of entities on Class1.
Class1.java:
class Class1 {
private Set<Class2> set;
//... other fields
}
In updateclass1.jspx:
<c:forEach items="${allClass2Instances}" var="class2">
<form:checkbox label="${class2.name}" path="set" value="${class2}"/><br/>
</c:forEach>
With the checkbox tag as above, when I display the page, the checkbox is ticked if the Class2 instance is part of the Set on class1, and unticked if it isn't. But when I hit submit, I get the following error:
Failed to convert property value of type 'java.lang.String[]' to required type 'java.util.Set' for property 'set'; nested exception is org.springframework.core.convert.ConversionFailedException: Unable to convert value "Name 1" from type 'java.lang.String' to type 'java.lang.Long'; nested exception is java.lang.NumberFormatException: For input string: "Name1"
As far as I can tell when the page is populated, the form:checkbox tag needs an instance to set the correct checked/unchecked value, but on submit the JSP is sending an array of class2.toString() values to a converter that expects the IDs. Conversely when I change the tag to the following:
<form:checkbox label="${class2.name}" path="set" value="${class2.id}"/><br/>
The binding works fine, but when I view the update page the checkboxes are not ticked / unticked correctly because the tag does not know that value being passed in is the object id.
How do I make the binding after submit consistent with what the checkbox tag expects?
In case it matters - this is all inside a scaffolding page generated by Roo.
Figured out how to make this work for now. If anyone comes up with a neater solution please add it and I'll mark it correct instead.
The problem above was being caused by needing ${InstanceOfClass2} to evaluate to different things in different places:
At the time of evaluation of the tag, <form:checkbox> needed an expression that evaluated to an actual instance of Class2
After the tag completed, the value attribute of the generated <input type="checkbox"> tag needs to be equal to a numerical ID field of an instance of Class2
The solution was to add a converter to my Class1Controller, eg:
Converter<Class2, String> getClass2Converter() {
return new Converter<Class2, String>() {
public String convert(Class2 instance) {
return "" + instance.getId();
}
};
}
Thus the expression ${InstanceOfClass2} evaluates to a Class2 instance for the checkbox tag, but when it comes to writing the actual HTML is converted to a numerical ID.
This approach is very messy when working with Roo. All of the other scaffolding relating to Class1 then wants to use this same Converter, so I started seeing a whole bunch of IDs everywhere that you would want to see Class2.name or other such fields. I solved this by modifying the Spring Roo <field:display> custom tag - added an attribute fmtCollectionToString that if present forces the tag to evaluate collections by iterating them and calling toString on each element, instead of calling spring:eval on the whole collection, which also seems to end up with the Converter being invoked.
Like I say, neater solutions greatly appreciated! If there's a way of making converters behave differently in different circumstances, for instance - still want to hear it.

Resources